mirror of https://github.com/minetest/minetest.git
Revert all commits up to (including) a704c04f
This commit is contained in:
parent
ffdf8dedb7
commit
32352e90da
|
@ -59,8 +59,6 @@ src/json/CMakeFiles/
|
||||||
src/json/libjsoncpp.a
|
src/json/libjsoncpp.a
|
||||||
src/sqlite/CMakeFiles/*
|
src/sqlite/CMakeFiles/*
|
||||||
src/sqlite/libsqlite3.a
|
src/sqlite/libsqlite3.a
|
||||||
src/client/CMakeFiles/
|
|
||||||
src/network/CMakeFiles/
|
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CPackConfig.cmake
|
CPackConfig.cmake
|
||||||
CPackSourceConfig.cmake
|
CPackSourceConfig.cmake
|
||||||
|
|
|
@ -12,7 +12,7 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||||
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 4)
|
set(VERSION_MINOR 4)
|
||||||
set(VERSION_PATCH 12)
|
set(VERSION_PATCH 11)
|
||||||
set(VERSION_PATCH_ORIG ${VERSION_PATCH})
|
set(VERSION_PATCH_ORIG ${VERSION_PATCH})
|
||||||
|
|
||||||
if(VERSION_EXTRA)
|
if(VERSION_EXTRA)
|
||||||
|
|
31
README.txt
31
README.txt
|
@ -103,30 +103,18 @@ Compiling on GNU/Linux:
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Install dependencies. Here's an example for Debian/Ubuntu:
|
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||||
$ sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libjsoncpp-dev
|
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev
|
||||||
|
|
||||||
You can install git for easily keeping your copy up to date.
|
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
||||||
If you dont want git, read below on how to get the source without git.
|
$ wget https://github.com/minetest/minetest/tarball/master -O master.tar.gz
|
||||||
This is an example for installing git on Debian/Ubuntu:
|
|
||||||
$ sudo apt-get install git-core
|
|
||||||
|
|
||||||
Download source (this is the URL to the latest of source repository, which might not work at all times) using git:
|
|
||||||
$ git clone --depth 1 https://github.com/minetest/minetest.git
|
|
||||||
$ cd minetest
|
|
||||||
|
|
||||||
Download minetest_game (otherwise only the "Minimal development test" game is available) using git:
|
|
||||||
$ git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game
|
|
||||||
|
|
||||||
Download source, without using git:
|
|
||||||
$ wget https://github.com/minetest/minetest/archive/master.tar.gz
|
|
||||||
$ tar xf master.tar.gz
|
$ tar xf master.tar.gz
|
||||||
$ cd minetest-master
|
$ cd minetest-minetest-286edd4 (or similar)
|
||||||
|
|
||||||
Download minetest_game, without using git:
|
Download minetest_game (otherwise only the "Minimal development test" game is available)
|
||||||
$ cd games/
|
$ cd games/
|
||||||
$ wget https://github.com/minetest/minetest_game/archive/master.tar.gz
|
$ wget https://github.com/minetest/minetest_game/tarball/master -O minetest_game.tar.gz
|
||||||
$ tar xf master.tar.gz
|
$ tar xf minetest_game.tar.gz
|
||||||
$ mv minetest_game-master minetest_game
|
$ mv minetest-minetest_game-* minetest_game
|
||||||
$ cd ..
|
$ cd ..
|
||||||
|
|
||||||
Build a version that runs directly from the source directory:
|
Build a version that runs directly from the source directory:
|
||||||
|
@ -134,7 +122,8 @@ $ cmake . -DRUN_IN_PLACE=1
|
||||||
$ make -j2
|
$ make -j2
|
||||||
|
|
||||||
Run it:
|
Run it:
|
||||||
$ ./bin/minetest
|
$ cd bin
|
||||||
|
$ ./minetest
|
||||||
|
|
||||||
- Use cmake . -LH to see all CMake options and their current state
|
- Use cmake . -LH to see all CMake options and their current state
|
||||||
- If you want to install it system-wide (or are making a distribution package), you will want to use -DRUN_IN_PLACE=0
|
- If you want to install it system-wide (or are making a distribution package), you will want to use -DRUN_IN_PLACE=0
|
||||||
|
|
|
@ -26,7 +26,7 @@ GAMES_TO_COPY = minetest_game
|
||||||
# Android Version code
|
# Android Version code
|
||||||
# Increase for each build!
|
# Increase for each build!
|
||||||
################################################################################
|
################################################################################
|
||||||
ANDROID_VERSION_CODE = 6
|
ANDROID_VERSION_CODE = 5
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# toolchain config for arm old processors
|
# toolchain config for arm old processors
|
||||||
|
|
|
@ -102,6 +102,7 @@ LOCAL_C_INCLUDES := \
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
jni/src/ban.cpp \
|
jni/src/ban.cpp \
|
||||||
|
jni/src/base64.cpp \
|
||||||
jni/src/camera.cpp \
|
jni/src/camera.cpp \
|
||||||
jni/src/cavegen.cpp \
|
jni/src/cavegen.cpp \
|
||||||
jni/src/chat.cpp \
|
jni/src/chat.cpp \
|
||||||
|
@ -112,6 +113,7 @@ LOCAL_SRC_FILES := \
|
||||||
jni/src/clientobject.cpp \
|
jni/src/clientobject.cpp \
|
||||||
jni/src/clouds.cpp \
|
jni/src/clouds.cpp \
|
||||||
jni/src/collision.cpp \
|
jni/src/collision.cpp \
|
||||||
|
jni/src/connection.cpp \
|
||||||
jni/src/content_abm.cpp \
|
jni/src/content_abm.cpp \
|
||||||
jni/src/content_cao.cpp \
|
jni/src/content_cao.cpp \
|
||||||
jni/src/content_cso.cpp \
|
jni/src/content_cso.cpp \
|
||||||
|
@ -188,6 +190,7 @@ LOCAL_SRC_FILES := \
|
||||||
jni/src/server.cpp \
|
jni/src/server.cpp \
|
||||||
jni/src/serverlist.cpp \
|
jni/src/serverlist.cpp \
|
||||||
jni/src/serverobject.cpp \
|
jni/src/serverobject.cpp \
|
||||||
|
jni/src/sha1.cpp \
|
||||||
jni/src/shader.cpp \
|
jni/src/shader.cpp \
|
||||||
jni/src/sky.cpp \
|
jni/src/sky.cpp \
|
||||||
jni/src/socket.cpp \
|
jni/src/socket.cpp \
|
||||||
|
@ -196,34 +199,22 @@ LOCAL_SRC_FILES := \
|
||||||
jni/src/staticobject.cpp \
|
jni/src/staticobject.cpp \
|
||||||
jni/src/subgame.cpp \
|
jni/src/subgame.cpp \
|
||||||
jni/src/test.cpp \
|
jni/src/test.cpp \
|
||||||
|
jni/src/tile.cpp \
|
||||||
jni/src/tool.cpp \
|
jni/src/tool.cpp \
|
||||||
jni/src/treegen.cpp \
|
jni/src/treegen.cpp \
|
||||||
jni/src/version.cpp \
|
jni/src/version.cpp \
|
||||||
jni/src/voxel.cpp \
|
jni/src/voxel.cpp \
|
||||||
jni/src/voxelalgorithms.cpp \
|
jni/src/voxelalgorithms.cpp \
|
||||||
jni/src/util/base64.cpp \
|
|
||||||
jni/src/util/directiontables.cpp \
|
jni/src/util/directiontables.cpp \
|
||||||
jni/src/util/numeric.cpp \
|
jni/src/util/numeric.cpp \
|
||||||
jni/src/util/pointedthing.cpp \
|
jni/src/util/pointedthing.cpp \
|
||||||
jni/src/util/serialize.cpp \
|
jni/src/util/serialize.cpp \
|
||||||
jni/src/util/sha1.cpp \
|
|
||||||
jni/src/util/string.cpp \
|
jni/src/util/string.cpp \
|
||||||
jni/src/util/timetaker.cpp \
|
jni/src/util/timetaker.cpp \
|
||||||
jni/src/touchscreengui.cpp \
|
jni/src/touchscreengui.cpp \
|
||||||
jni/src/database-leveldb.cpp \
|
jni/src/database-leveldb.cpp \
|
||||||
jni/src/settings.cpp \
|
jni/src/settings.cpp \
|
||||||
jni/src/wieldmesh.cpp \
|
jni/src/wieldmesh.cpp
|
||||||
jni/src/client/clientlauncher.cpp \
|
|
||||||
jni/src/client/tile.cpp
|
|
||||||
|
|
||||||
# Network
|
|
||||||
LOCAL_SRC_FILES += \
|
|
||||||
jni/src/network/connection.cpp \
|
|
||||||
jni/src/network/networkpacket.cpp \
|
|
||||||
jni/src/network/clientopcodes.cpp \
|
|
||||||
jni/src/network/serveropcodes.cpp \
|
|
||||||
jni/src/network/packethandlers/server.cpp \
|
|
||||||
jni/src/network/packethandlers/client.cpp
|
|
||||||
|
|
||||||
# lua api
|
# lua api
|
||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
|
|
|
@ -545,11 +545,12 @@ function table.copy(t, seen)
|
||||||
seen = seen or {}
|
seen = seen or {}
|
||||||
seen[t] = n
|
seen[t] = n
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] =
|
n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] =
|
||||||
(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v
|
type(v) ~= "table" and v or seen[v] or table.copy(v, seen)
|
||||||
end
|
end
|
||||||
return n
|
return n
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- mainmenu only functions
|
-- mainmenu only functions
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -564,7 +565,7 @@ if INIT == "mainmenu" then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function fgettext_ne(text, ...)
|
function fgettext(text, ...)
|
||||||
text = core.gettext(text)
|
text = core.gettext(text)
|
||||||
local arg = {n=select('#', ...), ...}
|
local arg = {n=select('#', ...), ...}
|
||||||
if arg.n >= 1 then
|
if arg.n >= 1 then
|
||||||
|
@ -586,11 +587,7 @@ if INIT == "mainmenu" then
|
||||||
end
|
end
|
||||||
text = result
|
text = result
|
||||||
end
|
end
|
||||||
return text
|
return core.formspec_escape(text)
|
||||||
end
|
|
||||||
|
|
||||||
function fgettext(text, ...)
|
|
||||||
return core.formspec_escape(fgettext_ne(text, ...))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -115,20 +115,11 @@ function core.serialize(x)
|
||||||
function dump_val(x)
|
function dump_val(x)
|
||||||
local tp = type(x)
|
local tp = type(x)
|
||||||
if x == nil then return "nil"
|
if x == nil then return "nil"
|
||||||
|
elseif tp == "number" then return string.format("%d", x)
|
||||||
elseif tp == "string" then return string.format("%q", x)
|
elseif tp == "string" then return string.format("%q", x)
|
||||||
elseif tp == "boolean" then return x and "true" or "false"
|
elseif tp == "boolean" then return x and "true" or "false"
|
||||||
elseif tp == "function" then
|
elseif tp == "function" then
|
||||||
return string.format("loadstring(%q)", string.dump(x))
|
return string.format("loadstring(%q)", string.dump(x))
|
||||||
elseif tp == "number" then
|
|
||||||
-- Serialize integers with string.format to prevent
|
|
||||||
-- scientific notation, which doesn't preserve
|
|
||||||
-- precision and breaks things like node position
|
|
||||||
-- hashes. Serialize floats normally.
|
|
||||||
if math.floor(x) == x then
|
|
||||||
return string.format("%d", x)
|
|
||||||
else
|
|
||||||
return tostring(x)
|
|
||||||
end
|
|
||||||
elseif tp == "table" then
|
elseif tp == "table" then
|
||||||
local vals = {}
|
local vals = {}
|
||||||
local idx_dumped = {}
|
local idx_dumped = {}
|
||||||
|
|
|
@ -229,28 +229,21 @@ core.register_chatcommand("setpassword", {
|
||||||
if not toname then
|
if not toname then
|
||||||
return false, "Name field required"
|
return false, "Name field required"
|
||||||
end
|
end
|
||||||
local act_str_past = "?"
|
local actstr = "?"
|
||||||
local act_str_pres = "?"
|
|
||||||
if not raw_password then
|
if not raw_password then
|
||||||
core.set_player_password(toname, "")
|
core.set_player_password(toname, "")
|
||||||
act_str_past = "cleared"
|
actstr = "cleared"
|
||||||
act_str_pres = "clears"
|
|
||||||
else
|
else
|
||||||
core.set_player_password(toname,
|
core.set_player_password(toname,
|
||||||
core.get_password_hash(toname,
|
core.get_password_hash(toname,
|
||||||
raw_password))
|
raw_password))
|
||||||
act_str_past = "set"
|
actstr = "set"
|
||||||
act_str_pres = "sets"
|
|
||||||
end
|
end
|
||||||
if toname ~= name then
|
if toname ~= name then
|
||||||
core.chat_send_player(toname, "Your password was "
|
core.chat_send_player(toname, "Your password was "
|
||||||
.. act_str_past .. " by " .. name)
|
.. actstr .. " by " .. name)
|
||||||
end
|
end
|
||||||
|
return true, "Password of player \"" .. toname .. "\" " .. actstr
|
||||||
core.log("action", name .. " " .. act_str_pres
|
|
||||||
.. " password of " .. toname .. ".")
|
|
||||||
|
|
||||||
return true, "Password of player \"" .. toname .. "\" " .. act_str_past
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -264,9 +257,6 @@ core.register_chatcommand("clearpassword", {
|
||||||
return false, "Name field required"
|
return false, "Name field required"
|
||||||
end
|
end
|
||||||
core.set_player_password(toname, '')
|
core.set_player_password(toname, '')
|
||||||
|
|
||||||
core.log("action", name .. " clears password of " .. toname .. ".")
|
|
||||||
|
|
||||||
return true, "Password of player \"" .. toname .. "\" cleared"
|
return true, "Password of player \"" .. toname .. "\" cleared"
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -414,14 +404,13 @@ core.register_chatcommand("set", {
|
||||||
})
|
})
|
||||||
|
|
||||||
core.register_chatcommand("deleteblocks", {
|
core.register_chatcommand("deleteblocks", {
|
||||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
params = "[here] [<pos1> <pos2>]",
|
||||||
description = "delete map blocks contained in area pos1 to pos2",
|
description = "delete map blocks contained in area pos1 to pos2",
|
||||||
privs = {server=true},
|
privs = {server=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local p1 = {}
|
local p1 = {}
|
||||||
local p2 = {}
|
local p2 = {}
|
||||||
local args = param:split(" ")
|
if param == "here" then
|
||||||
if args[1] == "here" then
|
|
||||||
local player = core.get_player_by_name(name)
|
local player = core.get_player_by_name(name)
|
||||||
if player == nil then
|
if player == nil then
|
||||||
core.log("error", "player is nil")
|
core.log("error", "player is nil")
|
||||||
|
@ -429,12 +418,6 @@ core.register_chatcommand("deleteblocks", {
|
||||||
end
|
end
|
||||||
p1 = player:getpos()
|
p1 = player:getpos()
|
||||||
p2 = p1
|
p2 = p1
|
||||||
|
|
||||||
if #args >= 2 then
|
|
||||||
local radius = tonumber(args[2]) or 0
|
|
||||||
p1 = vector.add(p1, radius)
|
|
||||||
p2 = vector.subtract(p2, radius)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
local pos1, pos2 = unpack(param:split(") ("))
|
local pos1, pos2 = unpack(param:split(") ("))
|
||||||
if pos1 == nil or pos2 == nil then
|
if pos1 == nil or pos2 == nil then
|
||||||
|
@ -587,9 +570,6 @@ core.register_chatcommand("rollback_check", {
|
||||||
.. " seconds=86400=24h, limit=5)",
|
.. " seconds=86400=24h, limit=5)",
|
||||||
privs = {rollback=true},
|
privs = {rollback=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
if not core.setting_getbool("enable_rollback_recording") then
|
|
||||||
return false, "Rollback functions are disabled."
|
|
||||||
end
|
|
||||||
local range, seconds, limit =
|
local range, seconds, limit =
|
||||||
param:match("(%d+) *(%d*) *(%d*)")
|
param:match("(%d+) *(%d*) *(%d*)")
|
||||||
range = tonumber(range) or 0
|
range = tonumber(range) or 0
|
||||||
|
@ -603,10 +583,6 @@ core.register_chatcommand("rollback_check", {
|
||||||
local name = puncher:get_player_name()
|
local name = puncher:get_player_name()
|
||||||
core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
|
core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
|
||||||
local actions = core.rollback_get_node_actions(pos, range, seconds, limit)
|
local actions = core.rollback_get_node_actions(pos, range, seconds, limit)
|
||||||
if not actions then
|
|
||||||
core.chat_send_player(name, "Rollback functions are disabled")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local num_actions = #actions
|
local num_actions = #actions
|
||||||
if num_actions == 0 then
|
if num_actions == 0 then
|
||||||
core.chat_send_player(name, "Nobody has touched"
|
core.chat_send_player(name, "Nobody has touched"
|
||||||
|
@ -638,9 +614,6 @@ core.register_chatcommand("rollback", {
|
||||||
description = "revert actions of a player; default for <seconds> is 60",
|
description = "revert actions of a player; default for <seconds> is 60",
|
||||||
privs = {rollback=true},
|
privs = {rollback=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
if not core.setting_getbool("enable_rollback_recording") then
|
|
||||||
return false, "Rollback functions are disabled."
|
|
||||||
end
|
|
||||||
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
|
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
|
||||||
if not target_name then
|
if not target_name then
|
||||||
local player_name = nil
|
local player_name = nil
|
||||||
|
|
|
@ -106,7 +106,7 @@ function core.facedir_to_dir(facedir)
|
||||||
{x=0, y=1, z=0}})
|
{x=0, y=1, z=0}})
|
||||||
|
|
||||||
--indexed into by a table of correlating facedirs
|
--indexed into by a table of correlating facedirs
|
||||||
[({[0]=1, 2, 3, 4,
|
[({[0]=1, 2, 3, 4,
|
||||||
5, 2, 6, 4,
|
5, 2, 6, 4,
|
||||||
6, 2, 5, 4,
|
6, 2, 5, 4,
|
||||||
1, 5, 3, 6,
|
1, 5, 3, 6,
|
||||||
|
@ -238,7 +238,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||||
|
|
||||||
core.log("action", placer:get_player_name() .. " places node "
|
core.log("action", placer:get_player_name() .. " places node "
|
||||||
.. def.name .. " at " .. core.pos_to_string(place_to))
|
.. def.name .. " at " .. core.pos_to_string(place_to))
|
||||||
|
|
||||||
local oldnode = core.get_node(place_to)
|
local oldnode = core.get_node(place_to)
|
||||||
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
||||||
|
|
||||||
|
@ -357,37 +357,19 @@ function core.item_drop(itemstack, dropper, pos)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
|
||||||
for _, callback in pairs(core.registered_on_item_eats) do
|
|
||||||
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
|
||||||
if result then
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if itemstack:take_item() ~= nil then
|
|
||||||
user:set_hp(user:get_hp() + hp_change)
|
|
||||||
|
|
||||||
if replace_with_item then
|
|
||||||
if itemstack:is_empty() then
|
|
||||||
itemstack:add_item(replace_with_item)
|
|
||||||
else
|
|
||||||
local inv = user:get_inventory()
|
|
||||||
if inv:room_for_item("main", {name=replace_with_item}) then
|
|
||||||
inv:add_item("main", replace_with_item)
|
|
||||||
else
|
|
||||||
local pos = user:getpos()
|
|
||||||
pos.y = math.floor(pos.y + 0.5)
|
|
||||||
core.add_item(pos, replace_with_item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
function core.item_eat(hp_change, replace_with_item)
|
function core.item_eat(hp_change, replace_with_item)
|
||||||
return function(itemstack, user, pointed_thing) -- closure
|
return function(itemstack, user, pointed_thing) -- closure
|
||||||
return core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
for _, callback in pairs(core.registered_on_item_eats) do
|
||||||
|
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||||
|
if result then
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -443,7 +425,7 @@ function core.node_dig(pos, node, digger)
|
||||||
|
|
||||||
local wielded = digger:get_wielded_item()
|
local wielded = digger:get_wielded_item()
|
||||||
local drops = core.get_node_drops(node.name, wielded:get_name())
|
local drops = core.get_node_drops(node.name, wielded:get_name())
|
||||||
|
|
||||||
local wdef = wielded:get_definition()
|
local wdef = wielded:get_definition()
|
||||||
local tp = wielded:get_tool_capabilities()
|
local tp = wielded:get_tool_capabilities()
|
||||||
local dp = core.get_dig_params(def.groups, tp)
|
local dp = core.get_dig_params(def.groups, tp)
|
||||||
|
@ -456,7 +438,7 @@ function core.node_dig(pos, node, digger)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
digger:set_wielded_item(wielded)
|
digger:set_wielded_item(wielded)
|
||||||
|
|
||||||
-- Handle drops
|
-- Handle drops
|
||||||
core.handle_node_drops(pos, drops, digger)
|
core.handle_node_drops(pos, drops, digger)
|
||||||
|
|
||||||
|
@ -467,7 +449,7 @@ function core.node_dig(pos, node, digger)
|
||||||
|
|
||||||
-- Remove node and update
|
-- Remove node and update
|
||||||
core.remove_node(pos)
|
core.remove_node(pos)
|
||||||
|
|
||||||
-- Run callback
|
-- Run callback
|
||||||
if def.after_dig_node then
|
if def.after_dig_node then
|
||||||
-- Copy pos and node because callback can modify them
|
-- Copy pos and node because callback can modify them
|
||||||
|
@ -525,7 +507,7 @@ core.nodedef_default = {
|
||||||
on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig
|
on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig
|
||||||
|
|
||||||
on_receive_fields = nil,
|
on_receive_fields = nil,
|
||||||
|
|
||||||
on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all,
|
on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all,
|
||||||
on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all,
|
on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all,
|
||||||
on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all,
|
on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all,
|
||||||
|
|
|
@ -16,15 +16,9 @@
|
||||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Global menu data
|
-- Global menu data
|
||||||
--------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
menudata = {}
|
menudata = {}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- Local cached values
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
local min_supp_proto = core.get_min_supp_proto()
|
|
||||||
local max_supp_proto = core.get_max_supp_proto()
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Menu helper functions
|
-- Menu helper functions
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -48,25 +42,6 @@ function image_column(tooltip, flagname)
|
||||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
function order_favorite_list(list)
|
|
||||||
local res = {}
|
|
||||||
--orders the favorite list after support
|
|
||||||
for i=1,#list,1 do
|
|
||||||
local fav = list[i]
|
|
||||||
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
|
||||||
table.insert(res, fav)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for i=1,#list,1 do
|
|
||||||
local fav = list[i]
|
|
||||||
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
|
||||||
table.insert(res, fav)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
function render_favorite(spec,render_details)
|
function render_favorite(spec,render_details)
|
||||||
local text = ""
|
local text = ""
|
||||||
|
@ -93,7 +68,6 @@ function render_favorite(spec,render_details)
|
||||||
end
|
end
|
||||||
|
|
||||||
local details = ""
|
local details = ""
|
||||||
local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
|
|
||||||
|
|
||||||
if spec.clients ~= nil and spec.clients_max ~= nil then
|
if spec.clients ~= nil and spec.clients_max ~= nil then
|
||||||
local clients_color = ''
|
local clients_color = ''
|
||||||
|
@ -113,17 +87,11 @@ function render_favorite(spec,render_details)
|
||||||
clients_color = '#ffba97' -- 90-100%: orange
|
clients_color = '#ffba97' -- 90-100%: orange
|
||||||
end
|
end
|
||||||
|
|
||||||
if grey_out then
|
|
||||||
clients_color = '#aaaaaa'
|
|
||||||
end
|
|
||||||
|
|
||||||
details = details ..
|
details = details ..
|
||||||
clients_color .. ',' ..
|
clients_color .. ',' ..
|
||||||
render_client_count(spec.clients) .. ',' ..
|
render_client_count(spec.clients) .. ',' ..
|
||||||
'/,' ..
|
'/,' ..
|
||||||
render_client_count(spec.clients_max) .. ','
|
render_client_count(spec.clients_max) .. ','
|
||||||
elseif grey_out then
|
|
||||||
details = details .. '#aaaaaa,?,/,?,'
|
|
||||||
else
|
else
|
||||||
details = details .. ',?,/,?,'
|
details = details .. ',?,/,?,'
|
||||||
end
|
end
|
||||||
|
@ -146,7 +114,7 @@ function render_favorite(spec,render_details)
|
||||||
details = details .. "0,"
|
details = details .. "0,"
|
||||||
end
|
end
|
||||||
|
|
||||||
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
return details .. text
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -227,7 +195,7 @@ function asyncOnlineFavourites()
|
||||||
nil,
|
nil,
|
||||||
function(result)
|
function(result)
|
||||||
if core.setting_getbool("public_serverlist") then
|
if core.setting_getbool("public_serverlist") then
|
||||||
menudata.favorites = order_favorite_list(result)
|
menudata.favorites = result
|
||||||
core.event_handler("Refresh")
|
core.event_handler("Refresh")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -257,21 +225,3 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
function is_server_protocol_compat(proto_min, proto_max)
|
|
||||||
return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13)))
|
|
||||||
end
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
function is_server_protocol_compat_or_error(proto_min, proto_max)
|
|
||||||
if not is_server_protocol_compat(proto_min, proto_max) then
|
|
||||||
gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " ..
|
|
||||||
((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") ..
|
|
||||||
", we " ..
|
|
||||||
((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"),
|
|
||||||
proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto)
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
local function modname_valid(name)
|
|
||||||
return not name:find("[^a-z0-9_]")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_formspec(data)
|
local function get_formspec(data)
|
||||||
|
|
||||||
|
@ -198,12 +195,10 @@ local function handle_buttons(this, fields)
|
||||||
for i,mod in ipairs(rawlist) do
|
for i,mod in ipairs(rawlist) do
|
||||||
if not mod.is_modpack and
|
if not mod.is_modpack and
|
||||||
mod.typ ~= "game_mod" then
|
mod.typ ~= "game_mod" then
|
||||||
if modname_valid(mod.name) then
|
if mod.enabled then
|
||||||
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
|
worldfile:set("load_mod_"..mod.name, "true")
|
||||||
else
|
else
|
||||||
if mod.enabled then
|
worldfile:set("load_mod_"..mod.name, "false")
|
||||||
gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
mods["load_mod_"..mod.name] = nil
|
mods["load_mod_"..mod.name] = nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -90,8 +90,6 @@ local function create_world_buttonhandler(this, fields)
|
||||||
|
|
||||||
local message = nil
|
local message = nil
|
||||||
|
|
||||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
|
||||||
|
|
||||||
if not menudata.worldlist:uid_exists_raw(worldname) then
|
if not menudata.worldlist:uid_exists_raw(worldname) then
|
||||||
core.setting_set("mg_name",fields["dd_mapgen"])
|
core.setting_set("mg_name",fields["dd_mapgen"])
|
||||||
message = core.create_world(worldname,gameindex)
|
message = core.create_world(worldname,gameindex)
|
||||||
|
@ -99,6 +97,8 @@ local function create_world_buttonhandler(this, fields)
|
||||||
message = fgettext("A world named \"$1\" already exists", worldname)
|
message = fgettext("A world named \"$1\" already exists", worldname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||||
|
|
||||||
if message ~= nil then
|
if message ~= nil then
|
||||||
gamedata.errormessage = message
|
gamedata.errormessage = message
|
||||||
else
|
else
|
||||||
|
|
|
@ -139,11 +139,7 @@ local function init_globals()
|
||||||
tv_main:add(tab_credits)
|
tv_main:add(tab_credits)
|
||||||
|
|
||||||
tv_main:set_global_event_handler(main_event_handler)
|
tv_main:set_global_event_handler(main_event_handler)
|
||||||
if PLATFORM ~= "Android" then
|
tv_main:set_fixed_size(false)
|
||||||
tv_main:set_fixed_size(true)
|
|
||||||
else
|
|
||||||
tv_main:set_fixed_size(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (PLATFORM == "Android") then
|
if not (PLATFORM == "Android") then
|
||||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||||
|
|
|
@ -122,36 +122,35 @@ end
|
||||||
function modstore.showdownloading(title)
|
function modstore.showdownloading(title)
|
||||||
local new_dlg = dialog_create("store_downloading",
|
local new_dlg = dialog_create("store_downloading",
|
||||||
function(data)
|
function(data)
|
||||||
return "size[6,2]label[0.25,0.75;" ..
|
return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
|
||||||
fgettext("Downloading $1, please wait...", data.title) .. "]"
|
" " .. data.title .. " " ..
|
||||||
|
fgettext("please wait...") .. "]"
|
||||||
end,
|
end,
|
||||||
function(this,fields)
|
function(this,fields)
|
||||||
if fields["btn_hidden_close_download"] ~= nil then
|
if fields["btn_hidden_close_download"] ~= nil then
|
||||||
if fields["btn_hidden_close_download"].successfull then
|
if fields["btn_hidden_close_download"].successfull then
|
||||||
modstore.lastmodentry = fields["btn_hidden_close_download"]
|
modstore.lastmodentry = fields["btn_hidden_close_download"]
|
||||||
modstore.successfulldialog(this)
|
modstore.successfulldialog()
|
||||||
else
|
else
|
||||||
this.parent:show()
|
|
||||||
this:delete()
|
|
||||||
modstore.lastmodtitle = ""
|
modstore.lastmodtitle = ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
this:delete()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end,
|
end,
|
||||||
nil)
|
nil,
|
||||||
|
modstore.tv_store)
|
||||||
|
|
||||||
new_dlg:set_parent(modstore.tv_store)
|
|
||||||
modstore.tv_store:hide()
|
|
||||||
new_dlg.data.title = title
|
new_dlg.data.title = title
|
||||||
new_dlg:show()
|
new_dlg:show()
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- @function [parent=#modstore] successfulldialog
|
-- @function [parent=#modstore] successfulldialog
|
||||||
function modstore.successfulldialog(downloading_dlg)
|
function modstore.successfulldialog()
|
||||||
local new_dlg = dialog_create("store_downloading",
|
local new_dlg = dialog_create("store_downloading",
|
||||||
function(data)
|
function(data)
|
||||||
local retval = ""
|
local retval = ""
|
||||||
|
@ -159,16 +158,18 @@ function modstore.successfulldialog(downloading_dlg)
|
||||||
if modstore.lastmodentry ~= nil then
|
if modstore.lastmodentry ~= nil then
|
||||||
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
|
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
|
||||||
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
|
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
|
||||||
|
|
||||||
|
|
||||||
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
|
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
|
||||||
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
|
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
|
||||||
|
|
||||||
end
|
end
|
||||||
retval = retval .. "button[2.2,1.5;1.5,0.5;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]"
|
retval = retval .. "button[2.5,1.5;1,0.5;btn_confirm_mod_successfull;" .. fgettext("ok") .. "]"
|
||||||
return retval
|
|
||||||
end,
|
end,
|
||||||
function(this,fields)
|
function(this,fields)
|
||||||
if fields["btn_confirm_mod_successfull"] ~= nil then
|
if fields["btn_confirm_mod_successfull"] ~= nil then
|
||||||
this.parent:show()
|
this.parent:show()
|
||||||
downloading_dlg:delete()
|
this:hide()
|
||||||
this:delete()
|
this:delete()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -176,10 +177,10 @@ function modstore.successfulldialog(downloading_dlg)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end,
|
end,
|
||||||
nil)
|
nil,
|
||||||
|
modstore.tv_store)
|
||||||
|
|
||||||
new_dlg:set_parent(modstore.tv_store)
|
new_dlg.data.title = title
|
||||||
modstore.tv_store:hide()
|
|
||||||
new_dlg:show()
|
new_dlg:show()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -216,9 +217,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields["btn_modstore_close"] then
|
if fields["btn_modstore_close"] then
|
||||||
local maintab = ui.find_by_name("maintab")
|
|
||||||
parent:hide()
|
parent:hide()
|
||||||
maintab:show()
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -229,7 +228,12 @@ function modstore.handle_buttons(parent, fields, name, data)
|
||||||
for i=1,#modstore.modlist_unsorted.data,1 do
|
for i=1,#modstore.modlist_unsorted.data,1 do
|
||||||
if modstore.modlist_unsorted.data[i].id == modid then
|
if modstore.modlist_unsorted.data[i].id == modid then
|
||||||
local moddetails = modstore.modlist_unsorted.data[i].details
|
local moddetails = modstore.modlist_unsorted.data[i].details
|
||||||
modstore.lastmodtitle = moddetails.title
|
|
||||||
|
if modstore.lastmodtitle ~= "" then
|
||||||
|
modstore.lastmodtitle = modstore.lastmodtitle .. ", "
|
||||||
|
end
|
||||||
|
|
||||||
|
modstore.lastmodtitle = modstore.lastmodtitle .. moddetails.title
|
||||||
|
|
||||||
if not core.handle_async(
|
if not core.handle_async(
|
||||||
function(param)
|
function(param)
|
||||||
|
@ -277,7 +281,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
||||||
texturename = modstore.modlist_unsorted.data[i].texturename
|
texturename = modstore.modlist_unsorted.data[i].texturename
|
||||||
},
|
},
|
||||||
function(result)
|
function(result)
|
||||||
--print("Result from async: " .. dump(result.successfull))
|
print("Result from async: " .. dump(result.successfull))
|
||||||
if result.successfull then
|
if result.successfull then
|
||||||
modmgr.installmod(result.filename,result.moddetails.basename)
|
modmgr.installmod(result.filename,result.moddetails.basename)
|
||||||
os.remove(result.filename)
|
os.remove(result.filename)
|
||||||
|
@ -295,7 +299,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
||||||
print("ERROR: async event failed")
|
print("ERROR: async event failed")
|
||||||
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
|
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
|
||||||
end
|
end
|
||||||
|
parent:hide()
|
||||||
modstore.showdownloading(modstore.lastmodtitle)
|
modstore.showdownloading(modstore.lastmodtitle)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -387,7 +391,7 @@ function modstore.getscreenshot(ypos,listentry)
|
||||||
listentry.details.screenshot_url == "") then
|
listentry.details.screenshot_url == "") then
|
||||||
|
|
||||||
if listentry.texturename == nil then
|
if listentry.texturename == nil then
|
||||||
listentry.texturename = defaulttexturedir .. "no_screenshot.png"
|
listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
|
||||||
end
|
end
|
||||||
|
|
||||||
return "image[0,".. ypos .. ";3,2;" ..
|
return "image[0,".. ypos .. ";3,2;" ..
|
||||||
|
|
|
@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
if modscreenshot == nil then
|
if modscreenshot == nil then
|
||||||
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
|
||||||
end
|
end
|
||||||
|
|
||||||
retval = retval
|
retval = retval
|
||||||
|
@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
else
|
else
|
||||||
--show dependencies
|
--show dependencies
|
||||||
|
|
||||||
retval = retval .. "," .. fgettext("Depends:") .. ","
|
retval = retval .. ",Depends:,"
|
||||||
|
|
||||||
local toadd = modmgr.get_dependencies(selected_mod.path)
|
local toadd = modmgr.get_dependencies(selected_mod.path)
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
"text,align=right;" .. -- clients
|
"text,align=right;" .. -- clients
|
||||||
"text,align=center,padding=0.25;" .. -- "/"
|
"text,align=center,padding=0.25;" .. -- "/"
|
||||||
"text,align=right,padding=0.25;" .. -- clients_max
|
"text,align=right,padding=0.25;" .. -- clients_max
|
||||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||||
"color,span=1;" ..
|
|
||||||
"text,padding=1]" -- name
|
"text,padding=1]" -- name
|
||||||
else
|
else
|
||||||
retval = retval .. "tablecolumns[text]"
|
retval = retval .. "tablecolumns[text]"
|
||||||
|
@ -89,6 +88,7 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
local function main_button_handler(tabview, fields, name, tabdata)
|
local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
if fields["te_name"] ~= nil then
|
if fields["te_name"] ~= nil then
|
||||||
gamedata.playername = fields["te_name"]
|
gamedata.playername = fields["te_name"]
|
||||||
core.setting_set("name", fields["te_name"])
|
core.setting_set("name", fields["te_name"])
|
||||||
|
@ -98,10 +98,6 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
local event = core.explode_table_event(fields["favourites"])
|
local event = core.explode_table_event(fields["favourites"])
|
||||||
if event.type == "DCL" then
|
if event.type == "DCL" then
|
||||||
if event.row <= #menudata.favorites then
|
if event.row <= #menudata.favorites then
|
||||||
if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min,
|
|
||||||
menudata.favorites[event.row].proto_max) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
gamedata.address = menudata.favorites[event.row].address
|
gamedata.address = menudata.favorites[event.row].address
|
||||||
gamedata.port = menudata.favorites[event.row].port
|
gamedata.port = menudata.favorites[event.row].port
|
||||||
gamedata.playername = fields["te_name"]
|
gamedata.playername = fields["te_name"]
|
||||||
|
@ -193,7 +189,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
local current_favourite = core.get_table_index("favourites")
|
local current_favourite = core.get_table_index("favourites")
|
||||||
if current_favourite == nil then return end
|
if current_favourite == nil then return end
|
||||||
core.delete_favorite(current_favourite)
|
core.delete_favorite(current_favourite)
|
||||||
menudata.favorites = order_favorite_list(core.get_favorites())
|
menudata.favorites = core.get_favorites()
|
||||||
tabdata.fav_selected = nil
|
tabdata.fav_selected = nil
|
||||||
|
|
||||||
core.setting_set("address","")
|
core.setting_set("address","")
|
||||||
|
@ -202,9 +198,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if (fields["btn_mp_connect"] ~= nil or
|
if fields["btn_mp_connect"] ~= nil or
|
||||||
fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and
|
fields["key_enter"] ~= nil then
|
||||||
fields["te_port"] ~= nil then
|
|
||||||
|
|
||||||
gamedata.playername = fields["te_name"]
|
gamedata.playername = fields["te_name"]
|
||||||
gamedata.password = fields["te_pwd"]
|
gamedata.password = fields["te_pwd"]
|
||||||
|
@ -219,11 +214,6 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
gamedata.servername = menudata.favorites[fav_idx].name
|
gamedata.servername = menudata.favorites[fav_idx].name
|
||||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||||
|
|
||||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
|
||||||
menudata.favorites[fav_idx].proto_max)then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
gamedata.servername = ""
|
gamedata.servername = ""
|
||||||
gamedata.serverdescription = ""
|
gamedata.serverdescription = ""
|
||||||
|
|
|
@ -42,10 +42,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
"text,align=right;" .. -- clients
|
"text,align=right;" .. -- clients
|
||||||
"text,align=center,padding=0.25;" .. -- "/"
|
"text,align=center,padding=0.25;" .. -- "/"
|
||||||
"text,align=right,padding=0.25;" .. -- clients_max
|
"text,align=right,padding=0.25;" .. -- clients_max
|
||||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||||
"color,span=1;" ..
|
|
||||||
"text,padding=1]" -- name
|
"text,padding=1]" -- name
|
||||||
else
|
else
|
||||||
retval = retval .. "tablecolumns[text]"
|
retval = retval .. "tablecolumns[text]"
|
||||||
|
@ -88,6 +87,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function main_button_handler(tabview, fields, name, tabdata)
|
local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
if fields["btn_start_singleplayer"] then
|
if fields["btn_start_singleplayer"] then
|
||||||
|
@ -159,11 +159,6 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
gamedata.servername = menudata.favorites[fav_idx].name
|
gamedata.servername = menudata.favorites[fav_idx].name
|
||||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||||
|
|
||||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
|
||||||
menudata.favorites[fav_idx].proto_max) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
gamedata.servername = ""
|
gamedata.servername = ""
|
||||||
gamedata.serverdescription = ""
|
gamedata.serverdescription = ""
|
||||||
|
|
|
@ -44,7 +44,7 @@ else()
|
||||||
/usr/include/irrlicht
|
/usr/include/irrlicht
|
||||||
)
|
)
|
||||||
|
|
||||||
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES libIrrlicht.so libIrrlicht.a Irrlicht
|
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES libIrrlicht.a Irrlicht
|
||||||
PATHS
|
PATHS
|
||||||
/usr/local/lib
|
/usr/local/lib
|
||||||
/usr/lib
|
/usr/lib
|
||||||
|
|
273
doc/lua_api.txt
273
doc/lua_api.txt
|
@ -1,4 +1,4 @@
|
||||||
Minetest Lua Modding API Reference 0.4.12
|
Minetest Lua Modding API Reference 0.4.11
|
||||||
=========================================
|
=========================================
|
||||||
* More information at <http://www.minetest.net/>
|
* More information at <http://www.minetest.net/>
|
||||||
* Developer Wiki: <http://dev.minetest.net/>
|
* Developer Wiki: <http://dev.minetest.net/>
|
||||||
|
@ -20,8 +20,7 @@ source code patches to <celeron55@gmail.com>.
|
||||||
|
|
||||||
Programming in Lua
|
Programming in Lua
|
||||||
------------------
|
------------------
|
||||||
If you have any difficulty in understanding this, please read
|
If you have any difficulty in understanding this, please read [Programming in Lua](http://www.lua.org/pil/).
|
||||||
[Programming in Lua](http://www.lua.org/pil/).
|
|
||||||
|
|
||||||
Startup
|
Startup
|
||||||
-------
|
-------
|
||||||
|
@ -594,14 +593,13 @@ set to level from `param2`.
|
||||||
Meshes
|
Meshes
|
||||||
------
|
------
|
||||||
If drawtype `mesh` is used, tiles should hold model materials textures.
|
If drawtype `mesh` is used, tiles should hold model materials textures.
|
||||||
Only static meshes are implemented.
|
Only static meshes are implemented.
|
||||||
For supported model formats see Irrlicht engine documentation.
|
For supported model formats see Irrlicht engine documentation.
|
||||||
|
|
||||||
|
|
||||||
Noise Parameters
|
Noise Parameters
|
||||||
----------------
|
----------------
|
||||||
Noise Parameters, or commonly called "`NoiseParams`", define the properties of
|
Noise Parameters, or commonly called "`NoiseParams`", define the properties of perlin noise.
|
||||||
perlin noise.
|
|
||||||
|
|
||||||
### `offset`
|
### `offset`
|
||||||
Offset that the noise is translated by (i.e. added) after calculation.
|
Offset that the noise is translated by (i.e. added) after calculation.
|
||||||
|
@ -681,26 +679,24 @@ All default ores are of the uniformly-distributed scatter type.
|
||||||
Randomly chooses a location and generates a cluster of ore.
|
Randomly chooses a location and generates a cluster of ore.
|
||||||
|
|
||||||
If `noise_params` is specified, the ore will be placed if the 3D perlin noise at
|
If `noise_params` is specified, the ore will be placed if the 3D perlin noise at
|
||||||
that point is greater than the `noise_threshold`, giving the ability to create
|
that point is greater than the `noise_threshold`, giving the ability to create a non-equal
|
||||||
a non-equal distribution of ore.
|
distribution of ore.
|
||||||
|
|
||||||
### `sheet`
|
### `sheet`
|
||||||
Creates a sheet of ore in a blob shape according to the 2D perlin noise
|
Creates a sheet of ore in a blob shape according to the 2D perlin noise described by `noise_params`.
|
||||||
described by `noise_params`. The relative height of the sheet can be
|
The relative height of the sheet can be controlled by the same perlin noise as well, by specifying
|
||||||
controlled by the same perlin noise as well, by specifying a non-zero
|
a non-zero `scale` parameter in `noise_params`.
|
||||||
`scale` parameter in `noise_params`.
|
|
||||||
|
|
||||||
**IMPORTANT**: The noise is not transformed by `offset` or `scale` when comparing
|
**IMPORTANT**: The noise is not transformed by `offset` or `scale` when comparing against the noise
|
||||||
against the noise threshold, but scale is used to determine relative height.
|
threshold, but scale is used to determine relative height.
|
||||||
The height of the blob is randomly scattered, with a maximum height of `clust_size`.
|
The height of the blob is randomly scattered, with a maximum height of `clust_size`.
|
||||||
|
|
||||||
`clust_scarcity` and `clust_num_ores` are ignored.
|
`clust_scarcity` and `clust_num_ores` are ignored.
|
||||||
|
|
||||||
This is essentially an improved version of the so-called "stratus" ore seen in
|
This is essentially an improved version of the so-called "stratus" ore seen in some unofficial mods.
|
||||||
some unofficial mods.
|
|
||||||
|
|
||||||
### `blob`
|
### `blob`
|
||||||
Creates a deformed sphere of ore according to 3d perlin noise described by
|
Creates a deformed sphere of ore according to 3d perlin noise described by
|
||||||
`noise_params`. The maximum size of the blob is `clust_size`, and
|
`noise_params`. The maximum size of the blob is `clust_size`, and
|
||||||
`clust_scarcity` has the same meaning as with the `scatter` type.
|
`clust_scarcity` has the same meaning as with the `scatter` type.
|
||||||
### `vein
|
### `vein
|
||||||
|
@ -745,75 +741,64 @@ The varying types of decorations that can be placed.
|
||||||
The default value is `simple`, and is currently the only type supported.
|
The default value is `simple`, and is currently the only type supported.
|
||||||
|
|
||||||
### `simple`
|
### `simple`
|
||||||
Creates a 1 times `H` times 1 column of a specified node (or a random node from
|
Creates a 1 times `H` times 1 column of a specified node (or a random node from a list, if a
|
||||||
a list, if a decoration list is specified). Can specify a certain node it must
|
decoration list is specified). Can specify a certain node it must spawn next to, such as water or
|
||||||
spawn next to, such as water or lava, for example. Can also generate a
|
lava, for example. Can also generate a decoration of random height between a specified lower and
|
||||||
decoration of random height between a specified lower and upper bound.
|
upper bound. This type of decoration is intended for placement of grass, flowers, cacti, papyri,
|
||||||
This type of decoration is intended for placement of grass, flowers, cacti,
|
and so on.
|
||||||
papyri, and so on.
|
|
||||||
|
|
||||||
### `schematic`
|
### `schematic`
|
||||||
Copies a box of `MapNodes` from a specified schematic file (or raw description).
|
Copies a box of `MapNodes` from a specified schematic file (or raw description). Can specify a
|
||||||
Can specify a probability of a node randomly appearing when placed.
|
probability of a node randomly appearing when placed. This decoration type is intended to be used
|
||||||
This decoration type is intended to be used for multi-node sized discrete
|
for multi-node sized discrete structures, such as trees, cave spikes, rocks, and so on.
|
||||||
structures, such as trees, cave spikes, rocks, and so on.
|
|
||||||
|
|
||||||
|
|
||||||
Schematic specifier
|
Schematic specifier
|
||||||
--------------------
|
--------------------
|
||||||
A schematic specifier identifies a schematic by either a filename to a
|
A schematic specifier identifies a schematic by either a filename to a Minetest Schematic file (`.mts`)
|
||||||
Minetest Schematic file (`.mts`) or through raw data supplied through Lua,
|
or through raw data supplied through Lua, in the form of a table. This table must specify two fields:
|
||||||
in the form of a table. This table must specify two fields:
|
|
||||||
|
|
||||||
* The `size` field is a 3D vector containing the dimensions of the provided schematic.
|
* The `size` field is a 3D vector containing the dimensions of the provided schematic.
|
||||||
* The `data` field is a flat table of MapNodes making up the schematic,
|
* The `data` field is a flat table of MapNodes making up the schematic, in the order of `[z [y [x]]]`.
|
||||||
in the order of `[z [y [x]]]`.
|
|
||||||
|
|
||||||
**Important**: The default value for `param1` in MapNodes here is `255`,
|
**Important**: The default value for `param1` in MapNodes here is `255`, which represents "always place".
|
||||||
which represents "always place".
|
|
||||||
|
|
||||||
In the bulk `MapNode` data, `param1`, instead of the typical light values,
|
In the bulk `MapNode` data, `param1`, instead of the typical light values, instead represents the
|
||||||
instead represents the probability of that node appearing in the structure.
|
probability of that node appearing in the structure.
|
||||||
|
|
||||||
When passed to `minetest.create_schematic`, probability is an integer value
|
When passed to `minetest.create_schematic`, probability is an integer value ranging from `0` to `255`:
|
||||||
ranging from `0` to `255`:
|
|
||||||
|
|
||||||
* A probability value of `0` means that node will never appear (0% chance).
|
* A probability value of `0` means that node will never appear (0% chance).
|
||||||
* A probability value of `255` means the node will always appear (100% chance).
|
* A probability value of `255` means the node will always appear (100% chance).
|
||||||
* If the probability value `p` is greater than `0`, then there is a
|
* If the probability value `p` is greater than `0`, then there is a `(p / 256 * 100)`% chance that node
|
||||||
`(p / 256 * 100)`% chance that node will appear when the schematic is
|
will appear when the schematic is placed on the map.
|
||||||
placed on the map.
|
|
||||||
|
|
||||||
**Important note**: Node aliases cannot be used for a raw schematic provided
|
**Important note**: Node aliases cannot be used for a raw schematic provided when registering as a decoration.
|
||||||
when registering as a decoration.
|
|
||||||
|
|
||||||
|
|
||||||
Schematic attributes
|
Schematic attributes
|
||||||
--------------------
|
--------------------
|
||||||
See section "Flag Specifier Format".
|
See section "Flag Specifier Format".
|
||||||
|
|
||||||
Currently supported flags: `place_center_x`, `place_center_y`,
|
Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`.
|
||||||
`place_center_z`, `force_placement`.
|
|
||||||
|
|
||||||
* `place_center_x`: Placement of this decoration is centered along the X axis.
|
* `place_center_x`: Placement of this decoration is centered along the X axis.
|
||||||
* `place_center_y`: Placement of this decoration is centered along the Y axis.
|
* `place_center_y`: Placement of this decoration is centered along the Y axis.
|
||||||
* `place_center_z`: Placement of this decoration is centered along the Z axis.
|
* `place_center_z`: Placement of this decoration is centered along the Z axis.
|
||||||
* `force_placement`: Schematic nodes other than "ignore" will replace existing nodes.
|
|
||||||
|
|
||||||
|
|
||||||
HUD element types
|
HUD element types
|
||||||
-----------------
|
-----------------
|
||||||
The position field is used for all element types.
|
The position field is used for all element types.
|
||||||
|
|
||||||
To account for differing resolutions, the position coordinates are the percentage
|
To account for differing resolutions, the position coordinates are the percentage of the screen,
|
||||||
of the screen, ranging in value from `0` to `1`.
|
ranging in value from `0` to `1`.
|
||||||
|
|
||||||
The name field is not yet used, but should contain a description of what the
|
The name field is not yet used, but should contain a description of what the HUD element represents.
|
||||||
HUD element represents. The direction field is the direction in which something
|
The direction field is the direction in which something is drawn.
|
||||||
is drawn.
|
|
||||||
|
|
||||||
`0` draws from left to right, `1` draws from right to left, `2` draws from
|
`0` draws from left to right, `1` draws from right to left, `2` draws from top to bottom,
|
||||||
top to bottom, and `3` draws from bottom to top.
|
and `3` draws from bottom to top.
|
||||||
|
|
||||||
The `alignment` field specifies how the item will be aligned. It ranges from `-1` to `1`,
|
The `alignment` field specifies how the item will be aligned. It ranges from `-1` to `1`,
|
||||||
with `0` being the center, `-1` is moved to the left/up, and `1` is to the right/down.
|
with `0` being the center, `-1` is moved to the left/up, and `1` is to the right/down.
|
||||||
|
@ -827,8 +812,7 @@ items in the HUD.
|
||||||
|
|
||||||
Below are the specific uses for fields in each type; fields not listed for that type are ignored.
|
Below are the specific uses for fields in each type; fields not listed for that type are ignored.
|
||||||
|
|
||||||
**Note**: Future revisions to the HUD API may be incompatible; the HUD API is still
|
**Note**: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages.
|
||||||
in the experimental stages.
|
|
||||||
|
|
||||||
### `image`
|
### `image`
|
||||||
Displays an image on the HUD.
|
Displays an image on the HUD.
|
||||||
|
@ -892,18 +876,15 @@ For helper functions see "Vector helpers".
|
||||||
|
|
||||||
Flag Specifier Format
|
Flag Specifier Format
|
||||||
---------------------
|
---------------------
|
||||||
Flags using the standardized flag specifier format can be specified in either of
|
Flags using the standardized flag specifier format can be specified in either of two ways, by string or table.
|
||||||
two ways, by string or table.
|
|
||||||
|
|
||||||
The string format is a comma-delimited set of flag names; whitespace and
|
The string format is a comma-delimited set of flag names; whitespace and unrecognized flag fields are ignored.
|
||||||
unrecognized flag fields are ignored. Specifying a flag in the string sets the
|
Specifying a flag in the string sets the flag, and specifying a flag prefixed by the string `"no"` explicitly
|
||||||
flag, and specifying a flag prefixed by the string `"no"` explicitly
|
|
||||||
clears the flag from whatever the default may be.
|
clears the flag from whatever the default may be.
|
||||||
|
|
||||||
In addition to the standard string flag format, the schematic flags field can
|
In addition to the standard string flag format, the schematic flags field can also be a table of flag names
|
||||||
also be a table of flag names to boolean values representing whether or not the
|
to boolean values representing whether or not the flag is set. Additionally, if a field with the flag name
|
||||||
flag is set. Additionally, if a field with the flag name prefixed with `"no"`
|
prefixed with `"no"` is present, mapped to a boolean of any value, the specified flag is unset.
|
||||||
is present, mapped to a boolean of any value, the specified flag is unset.
|
|
||||||
|
|
||||||
E.g. A flag field of value
|
E.g. A flag field of value
|
||||||
|
|
||||||
|
@ -1055,8 +1036,8 @@ Another example: Make red wool from white wool and red dye:
|
||||||
dropped as an item. If the node is wallmounted the wallmounted direction is
|
dropped as an item. If the node is wallmounted the wallmounted direction is
|
||||||
checked.
|
checked.
|
||||||
* `soil`: saplings will grow on nodes in this group
|
* `soil`: saplings will grow on nodes in this group
|
||||||
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
|
* `connect_to_raillike`: makes nodes of raillike drawtype connect to
|
||||||
connect to each other
|
other group members with same drawtype
|
||||||
|
|
||||||
### Known damage and digging time defining groups
|
### Known damage and digging time defining groups
|
||||||
* `crumbly`: dirt, sand
|
* `crumbly`: dirt, sand
|
||||||
|
@ -1196,8 +1177,7 @@ Damage calculation:
|
||||||
|
|
||||||
damage = 0
|
damage = 0
|
||||||
foreach group in cap.damage_groups:
|
foreach group in cap.damage_groups:
|
||||||
damage += cap.damage_groups[group] * limit(actual_interval /
|
damage += cap.damage_groups[group] * limit(actual_interval / cap.full_punch_interval, 0.0, 1.0)
|
||||||
cap.full_punch_interval, 0.0, 1.0)
|
|
||||||
* (object.armor_groups[group] / 100.0)
|
* (object.armor_groups[group] / 100.0)
|
||||||
-- Where object.armor_groups[group] is 0 for inexistent values
|
-- Where object.armor_groups[group] is 0 for inexistent values
|
||||||
return damage
|
return damage
|
||||||
|
@ -1205,7 +1185,7 @@ Damage calculation:
|
||||||
Client predicts damage based on damage groups. Because of this, it is able to
|
Client predicts damage based on damage groups. Because of this, it is able to
|
||||||
give an immediate response when an entity is damaged or dies; the response is
|
give an immediate response when an entity is damaged or dies; the response is
|
||||||
pre-defined somehow (e.g. by defining a sprite animation) (not implemented;
|
pre-defined somehow (e.g. by defining a sprite animation) (not implemented;
|
||||||
TODO).
|
TODO).
|
||||||
Currently a smoke puff will appear when an entity dies.
|
Currently a smoke puff will appear when an entity dies.
|
||||||
|
|
||||||
The group `immortal` completely disables normal damage.
|
The group `immortal` completely disables normal damage.
|
||||||
|
@ -1218,8 +1198,8 @@ On the Lua side, every punch calls:
|
||||||
|
|
||||||
entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||||
|
|
||||||
This should never be called directly, because damage is usually not handled by
|
This should never be called directly, because damage is usually not handled by the entity
|
||||||
the entity itself.
|
itself.
|
||||||
|
|
||||||
* `puncher` is the object performing the punch. Can be `nil`. Should never be
|
* `puncher` is the object performing the punch. Can be `nil`. Should never be
|
||||||
accessed unless absolutely required, to encourage interoperability.
|
accessed unless absolutely required, to encourage interoperability.
|
||||||
|
@ -1264,14 +1244,12 @@ Example stuff:
|
||||||
print(dump(meta:to_table()))
|
print(dump(meta:to_table()))
|
||||||
meta:from_table({
|
meta:from_table({
|
||||||
inventory = {
|
inventory = {
|
||||||
main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "",
|
main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "", [5] = "", [6] = "",
|
||||||
[5] = "", [6] = "", [7] = "", [8] = "", [9] = "",
|
[7] = "", [8] = "", [9] = "", [10] = "", [11] = "", [12] = "", [13] = "",
|
||||||
[10] = "", [11] = "", [12] = "", [13] = "",
|
[14] = "default:cobble", [15] = "", [16] = "", [17] = "", [18] = "",
|
||||||
[14] = "default:cobble", [15] = "", [16] = "", [17] = "",
|
[19] = "", [20] = "default:cobble", [21] = "", [22] = "", [23] = "",
|
||||||
[18] = "", [19] = "", [20] = "default:cobble", [21] = "",
|
[24] = "", [25] = "", [26] = "", [27] = "", [28] = "", [29] = "", [30] = "",
|
||||||
[22] = "", [23] = "", [24] = "", [25] = "", [26] = "",
|
[31] = "", [32] = ""}
|
||||||
[27] = "", [28] = "", [29] = "", [30] = "", [31] = "",
|
|
||||||
[32] = ""}
|
|
||||||
},
|
},
|
||||||
fields = {
|
fields = {
|
||||||
formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
|
formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
|
||||||
|
@ -1871,9 +1849,6 @@ and `minetest.auth_reload` call the authetification handler.
|
||||||
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||||
* `minetest.find_nodes_in_area(minp, maxp, nodenames)`: returns a list of positions
|
* `minetest.find_nodes_in_area(minp, maxp, nodenames)`: returns a list of positions
|
||||||
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||||
* `minetest.find_nodes_in_area_under_air(minp, maxp, nodenames)`: returns a list of positions
|
|
||||||
* returned positions are nodes with a node air above
|
|
||||||
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
|
||||||
* `minetest.get_perlin(noiseparams)`
|
* `minetest.get_perlin(noiseparams)`
|
||||||
* `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
|
* `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
|
||||||
* Return world-specific perlin noise (`int(worldseed)+seeddiff`)
|
* Return world-specific perlin noise (`int(worldseed)+seeddiff`)
|
||||||
|
@ -1891,10 +1866,8 @@ and `minetest.auth_reload` call the authetification handler.
|
||||||
`mgname`, `seed`, `chunksize`, `water_level`, and `flags`.
|
`mgname`, `seed`, `chunksize`, `water_level`, and `flags`.
|
||||||
* `minetest.set_mapgen_params(MapgenParams)`
|
* `minetest.set_mapgen_params(MapgenParams)`
|
||||||
* Set map generation parameters
|
* Set map generation parameters
|
||||||
* Function cannot be called after the registration period; only initialization
|
* Function cannot be called after the registration period; only initialization and `on_mapgen_init`
|
||||||
and `on_mapgen_init`
|
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`, and `flags`.
|
||||||
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`,
|
|
||||||
and `flags`.
|
|
||||||
* Leave field unset to leave that parameter unchanged
|
* Leave field unset to leave that parameter unchanged
|
||||||
* `flags` contains a comma-delimited string of flags to set,
|
* `flags` contains a comma-delimited string of flags to set,
|
||||||
or if the prefix `"no"` is attached, clears instead.
|
or if the prefix `"no"` is attached, clears instead.
|
||||||
|
@ -1953,9 +1926,6 @@ and `minetest.auth_reload` call the authetification handler.
|
||||||
* `minetest.create_detached_inventory(name, callbacks)`: returns an `InvRef`
|
* `minetest.create_detached_inventory(name, callbacks)`: returns an `InvRef`
|
||||||
* callbacks: See "Detached inventory callbacks"
|
* callbacks: See "Detached inventory callbacks"
|
||||||
* Creates a detached inventory. If it already exists, it is cleared.
|
* Creates a detached inventory. If it already exists, it is cleared.
|
||||||
* `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`:
|
|
||||||
returns left over ItemStack
|
|
||||||
* See `minetest.item_eat` and `minetest.register_on_item_eat`
|
|
||||||
|
|
||||||
### Formspec
|
### Formspec
|
||||||
* `minetest.show_formspec(playername, formname, formspec)`
|
* `minetest.show_formspec(playername, formname, formspec)`
|
||||||
|
@ -2067,11 +2037,7 @@ These functions return the leftover itemstack.
|
||||||
* `minetest.item_drop(itemstack, dropper, pos)`
|
* `minetest.item_drop(itemstack, dropper, pos)`
|
||||||
* Drop the item
|
* Drop the item
|
||||||
* `minetest.item_eat(hp_change, replace_with_item)`
|
* `minetest.item_eat(hp_change, replace_with_item)`
|
||||||
* Eat the item.
|
* Eat the item. `replace_with_item` can be `nil`.
|
||||||
* `replace_with_item` is the itemstring which is added to the inventory.
|
|
||||||
If the player is eating a stack, then replace_with_item goes to a
|
|
||||||
different spot. Can be `nil`
|
|
||||||
* See `minetest.do_item_eat`
|
|
||||||
|
|
||||||
### Defaults for the `on_punch` and `on_dig` node definition callbacks
|
### Defaults for the `on_punch` and `on_dig` node definition callbacks
|
||||||
* `minetest.node_punch(pos, node, puncher, pointed_thing)`
|
* `minetest.node_punch(pos, node, puncher, pointed_thing)`
|
||||||
|
@ -2128,15 +2094,12 @@ These functions return the leftover itemstack.
|
||||||
* Create a schematic from the volume of map specified by the box formed by p1 and p2.
|
* Create a schematic from the volume of map specified by the box formed by p1 and p2.
|
||||||
* Apply the specified probability values to the specified nodes in `probability_list`.
|
* Apply the specified probability values to the specified nodes in `probability_list`.
|
||||||
* `probability_list` is an array of tables containing two fields, `pos` and `prob`.
|
* `probability_list` is an array of tables containing two fields, `pos` and `prob`.
|
||||||
* `pos` is the 3D vector specifying the absolute coordinates of the
|
* `pos` is the 3D vector specifying the absolute coordinates of the node being modified,
|
||||||
node being modified,
|
|
||||||
* `prob` is the integer value from `0` to `255` of the probability (see: Schematic specifier).
|
* `prob` is the integer value from `0` to `255` of the probability (see: Schematic specifier).
|
||||||
* If there are two or more entries with the same pos value, the
|
* If there are two or more entries with the same pos value, the last entry is used.
|
||||||
last entry is used.
|
|
||||||
* If `pos` is not inside the box formed by `p1` and `p2`, it is ignored.
|
* If `pos` is not inside the box formed by `p1` and `p2`, it is ignored.
|
||||||
* If `probability_list` equals `nil`, no probabilities are applied.
|
* If `probability_list` equals `nil`, no probabilities are applied.
|
||||||
* Slice probability works in the same manner, except takes a field
|
* Slice probability works in the same manner, except takes a field called `ypos` instead which
|
||||||
called `ypos` instead which
|
|
||||||
indicates the y position of the slice with a probability applied.
|
indicates the y position of the slice with a probability applied.
|
||||||
* If slice probability list equals `nil`, no slice probabilities are applied.
|
* If slice probability list equals `nil`, no slice probabilities are applied.
|
||||||
* Saves schematic in the Minetest Schematic format to filename.
|
* Saves schematic in the Minetest Schematic format to filename.
|
||||||
|
@ -2281,7 +2244,7 @@ Class reference
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
### `NodeMetaRef`
|
### `NodeMetaRef`
|
||||||
Node metadata: reference extra data and functionality stored in a node.
|
Node metadata: reference extra data and functionality stored in a node.
|
||||||
Can be gotten via `minetest.get_meta(pos)`.
|
Can be gotten via `minetest.get_meta(pos)`.
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
|
@ -2297,7 +2260,7 @@ Can be gotten via `minetest.get_meta(pos)`.
|
||||||
* See "Node Metadata"
|
* See "Node Metadata"
|
||||||
|
|
||||||
### `NoteTimerRef`
|
### `NoteTimerRef`
|
||||||
Node Timers: a high resolution persistent per-node timer.
|
Node Timers: a high resolution persistent per-node timer.
|
||||||
Can be gotten via `minetest.get_node_timer(pos)`.
|
Can be gotten via `minetest.get_node_timer(pos)`.
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
|
@ -2325,7 +2288,6 @@ This is basically a reference to a C++ `ServerActiveObject`
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
* `remove()`: remove object (after returning from Lua)
|
* `remove()`: remove object (after returning from Lua)
|
||||||
* Note: Doesn't work on players, use minetest.kick_player instead
|
|
||||||
* `getpos()`: returns `{x=num, y=num, z=num}`
|
* `getpos()`: returns `{x=num, y=num, z=num}`
|
||||||
* `setpos(pos)`; `pos`=`{x=num, y=num, z=num}`
|
* `setpos(pos)`; `pos`=`{x=num, y=num, z=num}`
|
||||||
* `moveto(pos, continuous=false)`: interpolated move
|
* `moveto(pos, continuous=false)`: interpolated move
|
||||||
|
@ -2398,8 +2360,7 @@ This is basically a reference to a C++ `ServerActiveObject`
|
||||||
* `gravity`: multiplier to default gravity value (default: `1`)
|
* `gravity`: multiplier to default gravity value (default: `1`)
|
||||||
* `sneak`: whether player can sneak (default: `true`)
|
* `sneak`: whether player can sneak (default: `true`)
|
||||||
* `sneak_glitch`: whether player can use the sneak glitch (default: `true`)
|
* `sneak_glitch`: whether player can use the sneak glitch (default: `true`)
|
||||||
* `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID
|
* `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID number on success
|
||||||
number on success
|
|
||||||
* `hud_remove(id)`: remove the HUD element of the specified id
|
* `hud_remove(id)`: remove the HUD element of the specified id
|
||||||
* `hud_change(id, stat, value)`: change a value of a previously added HUD element
|
* `hud_change(id, stat, value)`: change a value of a previously added HUD element
|
||||||
* element `stat` values: `position`, `name`, `scale`, `text`, `number`, `item`, `dir`
|
* element `stat` values: `position`, `name`, `scale`, `text`, `number`, `item`, `dir`
|
||||||
|
@ -2431,16 +2392,13 @@ This is basically a reference to a C++ `ServerActiveObject`
|
||||||
* `override_day_night_ratio(ratio or nil)`
|
* `override_day_night_ratio(ratio or nil)`
|
||||||
* `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount
|
* `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount
|
||||||
* `nil`: Disables override, defaulting to sunlight based on day-night cycle
|
* `nil`: Disables override, defaulting to sunlight based on day-night cycle
|
||||||
* `set_local_animation(walk, dig, walk+dig, frame_speed=frame_speed)`
|
* `set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, frame_speed=30)`:
|
||||||
|
set animation for player model in third person view
|
||||||
set animation for player model in third person view
|
* stand/idle animation key frames
|
||||||
|
* walk animation key frames
|
||||||
set_local_animation({x=0, y=79}, -- < stand/idle animation key frames
|
* dig animation key frames
|
||||||
{x=168, y=187}, -- < walk animation key frames
|
* walk+dig animation key frames
|
||||||
{x=189, y=198}, -- < dig animation key frames
|
* animation frame speed
|
||||||
{x=200, y=219}, -- < walk+dig animation key frames
|
|
||||||
frame_speed=30): -- < animation frame speed
|
|
||||||
|
|
||||||
* `set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})`: defines offset value for camera per player
|
* `set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})`: defines offset value for camera per player
|
||||||
* in first person view
|
* in first person view
|
||||||
* in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
|
* in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
|
||||||
|
@ -2527,7 +2485,7 @@ It can be created via `PseudoRandom(seed)`.
|
||||||
### `PerlinNoise`
|
### `PerlinNoise`
|
||||||
A perlin noise generator.
|
A perlin noise generator.
|
||||||
It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
|
It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
|
||||||
or `PerlinNoise(noiseparams)`.
|
or `PerlinNoise(noiseparams)`.
|
||||||
Alternatively with `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
|
Alternatively with `minetest.get_perlin(seeddiff, octaves, persistence, scale)`
|
||||||
or `minetest.get_perlin(noiseparams)`.
|
or `minetest.get_perlin(noiseparams)`.
|
||||||
|
|
||||||
|
@ -2561,43 +2519,36 @@ It can be created via `VoxelManip()` or `minetest.get_voxel_manip()`.
|
||||||
The map will be pre-loaded if two positions are passed to either.
|
The map will be pre-loaded if two positions are passed to either.
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
* `read_from_map(p1, p2)`: Reads a chunk of map from the map containing the
|
* `read_from_map(p1, p2)`: Reads a chunk of map from the map containing the region formed by `p1` and `p2`.
|
||||||
region formed by `p1` and `p2`.
|
|
||||||
* returns actual emerged `pmin`, actual emerged `pmax`
|
* returns actual emerged `pmin`, actual emerged `pmax`
|
||||||
* `write_to_map()`: Writes the data loaded from the `VoxelManip` back to the map.
|
* `write_to_map()`: Writes the data loaded from the `VoxelManip` back to the map.
|
||||||
* **important**: data must be set using `VoxelManip:set_data` before calling this
|
* **important**: data must be set using `VoxelManip:set_data` before calling this
|
||||||
* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in
|
* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in the `VoxelManip` at that position
|
||||||
the `VoxelManip` at that position
|
* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at that position
|
||||||
* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at
|
|
||||||
that position
|
|
||||||
* `get_data()`: Gets the data read into the `VoxelManip` object
|
* `get_data()`: Gets the data read into the `VoxelManip` object
|
||||||
* returns raw node data is in the form of an array of node content IDs
|
* returns raw node data is in the form of an array of node content IDs
|
||||||
* `set_data(data)`: Sets the data contents of the `VoxelManip` object
|
* `set_data(data)`: Sets the data contents of the `VoxelManip` object
|
||||||
* `update_map()`: Update map after writing chunk back to map.
|
* `update_map()`: Update map after writing chunk back to map.
|
||||||
* To be used only by `VoxelManip` objects created by the mod itself;
|
* To be used only by `VoxelManip` objects created by the mod itself; not a `VoxelManip` that was
|
||||||
not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object`
|
retrieved from `minetest.get_mapgen_object`
|
||||||
* `set_lighting(light, p1, p2)`: Set the lighting within the `VoxelManip` to a uniform value
|
* `set_lighting(light, p1, p2)`: Set the lighting within the `VoxelManip` to a uniform value
|
||||||
* `light` is a table, `{day=<0...15>, night=<0...15>}`
|
* `light` is a table, `{day=<0...15>, night=<0...15>}`
|
||||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||||
* (`p1`, `p2`) is the area in which lighting is set;
|
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area if left out
|
||||||
defaults to the whole area if left out
|
|
||||||
* `get_light_data()`: Gets the light data read into the `VoxelManip` object
|
* `get_light_data()`: Gets the light data read into the `VoxelManip` object
|
||||||
* Returns an array (indices 1 to volume) of integers ranging from `0` to `255`
|
* Returns an array (indices 1 to volume) of integers ranging from `0` to `255`
|
||||||
* Each value is the bitwise combination of day and night light values (`0` to `15` each)
|
* Each value is the bitwise combination of day and night light values (`0` to `15` each)
|
||||||
* `light = day + (night * 16)`
|
* `light = day + (night * 16)`
|
||||||
* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node
|
* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node in the `VoxelManip`
|
||||||
in the `VoxelManip`
|
|
||||||
* expects lighting data in the same format that `get_light_data()` returns
|
* expects lighting data in the same format that `get_light_data()` returns
|
||||||
* `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object
|
* `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object
|
||||||
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
||||||
* `calc_lighting(p1, p2)`: Calculate lighting within the `VoxelManip`
|
* `calc_lighting(p1, p2)`: Calculate lighting within the `VoxelManip`
|
||||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||||
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area
|
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area if left out
|
||||||
if left out
|
|
||||||
* `update_liquids()`: Update liquid flow
|
* `update_liquids()`: Update liquid flow
|
||||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator
|
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator had been modified since
|
||||||
had been modified since the last read from map, due to a call to
|
the last read from map, due to a call to `minetest.set_data()` on the loaded area elsewhere
|
||||||
`minetest.set_data()` on the loaded area elsewhere
|
|
||||||
* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
|
* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
|
||||||
|
|
||||||
### `VoxelArea`
|
### `VoxelArea`
|
||||||
|
@ -2606,12 +2557,10 @@ It can be created via `VoxelArea:new{MinEdge=pmin, MaxEdge=pmax}`.
|
||||||
The coordinates are *inclusive*, like most other things in Minetest.
|
The coordinates are *inclusive*, like most other things in Minetest.
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
* `getExtent()`: returns a 3D vector containing the size of the area formed by
|
* `getExtent()`: returns a 3D vector containing the size of the area formed by `MinEdge` and `MaxEdge`
|
||||||
`MinEdge` and `MaxEdge`
|
|
||||||
* `getVolume()`: returns the volume of the area formed by `MinEdge` and `MaxEdge`
|
* `getVolume()`: returns the volume of the area formed by `MinEdge` and `MaxEdge`
|
||||||
* `index(x, y, z)`: returns the index of an absolute position in a flat array starting at `1`
|
* `index(x, y, z)`: returns the index of an absolute position in a flat array starting at `1`
|
||||||
* useful for things like `VoxelManip`, raw Schematic specifiers,
|
* useful for things like `VoxelManip`, raw Schematic specifiers, `PerlinNoiseMap:get2d`/`3dMap`, and so on
|
||||||
`PerlinNoiseMap:get2d`/`3dMap`, and so on
|
|
||||||
* `indexp(p)`: same as above, except takes a vector
|
* `indexp(p)`: same as above, except takes a vector
|
||||||
* `position(i)`: returns the absolute position vector corresponding to index `i`
|
* `position(i)`: returns the absolute position vector corresponding to index `i`
|
||||||
* `contains(x, y, z)`: check if (`x`,`y`,`z`) is inside area formed by `MinEdge` and `MaxEdge`
|
* `contains(x, y, z)`: check if (`x`,`y`,`z`) is inside area formed by `MinEdge` and `MaxEdge`
|
||||||
|
@ -2638,39 +2587,37 @@ It can be created via `Settings(filename)`.
|
||||||
|
|
||||||
Mapgen objects
|
Mapgen objects
|
||||||
--------------
|
--------------
|
||||||
A mapgen object is a construct used in map generation. Mapgen objects can be used
|
A mapgen object is a construct used in map generation. Mapgen objects can be used by an `on_generate`
|
||||||
by an `on_generate` callback to speed up operations by avoiding unnecessary
|
callback to speed up operations by avoiding unnecessary recalculations; these can be retrieved using the
|
||||||
recalculations; these can be retrieved using the `minetest.get_mapgen_object()`
|
`minetest.get_mapgen_object()` function. If the requested Mapgen object is unavailable, or
|
||||||
function. If the requested Mapgen object is unavailable, or `get_mapgen_object()`
|
`get_mapgen_object()` was called outside of an `on_generate()` callback, `nil` is returned.
|
||||||
was called outside of an `on_generate()` callback, `nil` is returned.
|
|
||||||
|
|
||||||
The following Mapgen objects are currently available:
|
The following Mapgen objects are currently available:
|
||||||
|
|
||||||
### `voxelmanip`
|
### `voxelmanip`
|
||||||
This returns three values; the `VoxelManip` object to be used, minimum and maximum
|
This returns three values; the `VoxelManip` object to be used, minimum and maximum emerged position, in that
|
||||||
emerged position, in that order. All mapgens support this object.
|
order. All mapgens support this object.
|
||||||
|
|
||||||
### `heightmap`
|
### `heightmap`
|
||||||
Returns an array containing the y coordinates of the ground levels of nodes in
|
Returns an array containing the y coordinates of the ground levels of nodes in the most recently
|
||||||
the most recently generated chunk by the current mapgen.
|
generated chunk by the current mapgen.
|
||||||
|
|
||||||
### `biomemap`
|
### `biomemap`
|
||||||
Returns an array containing the biome IDs of nodes in the most recently
|
Returns an array containing the biome IDs of nodes in the most recently generated chunk by the
|
||||||
generated chunk by the current mapgen.
|
current mapgen.
|
||||||
|
|
||||||
### `heatmap`
|
### `heatmap`
|
||||||
Returns an array containing the temperature values of nodes in the most
|
Returns an array containing the temperature values of nodes in the most recently generated chunk by
|
||||||
recently generated chunk by the current mapgen.
|
the current mapgen.
|
||||||
|
|
||||||
### `humiditymap`
|
### `humiditymap`
|
||||||
Returns an array containing the humidity values of nodes in the most recently
|
Returns an array containing the humidity values of nodes in the most recently generated chunk by the
|
||||||
generated chunk by the current mapgen.
|
current mapgen.
|
||||||
|
|
||||||
### `gennotify`
|
### `gennotify`
|
||||||
Returns a table mapping requested generation notification types to arrays of
|
Returns a table mapping requested generation notification types to arrays of positions at which the
|
||||||
positions at which the corresponding generated structures are located at within
|
corresponding generated structures are located at within the current chunk. To set the capture of positions
|
||||||
the current chunk. To set the capture of positions of interest to be recorded
|
of interest to be recorded on generate, use `minetest.set_gen_notify()`.
|
||||||
on generate, use `minetest.set_gen_notify()`.
|
|
||||||
|
|
||||||
Possible fields of the table returned are:
|
Possible fields of the table returned are:
|
||||||
|
|
||||||
|
@ -2682,8 +2629,7 @@ Possible fields of the table returned are:
|
||||||
* `large_cave_end`
|
* `large_cave_end`
|
||||||
* `decoration`
|
* `decoration`
|
||||||
|
|
||||||
Decorations have a key in the format of `"decoration#id"`, where `id` is the
|
Decorations have a key in the format of `"decoration#id"`, where `id` is the numeric unique decoration ID.
|
||||||
numeric unique decoration ID.
|
|
||||||
|
|
||||||
Registered entities
|
Registered entities
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -2730,8 +2676,7 @@ L-system trees
|
||||||
angle, --num angle in deg
|
angle, --num angle in deg
|
||||||
iterations, --num max # of iterations, usually 2 -5
|
iterations, --num max # of iterations, usually 2 -5
|
||||||
random_level, --num factor to lower nr of iterations, usually 0 - 3
|
random_level, --num factor to lower nr of iterations, usually 0 - 3
|
||||||
trunk_type, --string single/double/crossed) type of trunk: 1 node,
|
trunk_type, --string single/double/crossed) type of trunk: 1 node, 2x2 nodes or 3x3 in cross shape
|
||||||
-- 2x2 nodes or 3x3 in cross shape
|
|
||||||
thin_branches, --boolean true -> use thin (1 node) branches
|
thin_branches, --boolean true -> use thin (1 node) branches
|
||||||
fruit, --string fruit node name
|
fruit, --string fruit node name
|
||||||
fruit_chance, --num chance (0-100) to replace leaves with fruit node
|
fruit_chance, --num chance (0-100) to replace leaves with fruit node
|
||||||
|
@ -3193,10 +3138,8 @@ Definition tables
|
||||||
schematic = {
|
schematic = {
|
||||||
size = {x=4, y=6, z=4},
|
size = {x=4, y=6, z=4},
|
||||||
data = {
|
data = {
|
||||||
{name="default:cobble", param1=255, param2=0},
|
{name="cobble", param1=255, param2=0},
|
||||||
{name="default:dirt_with_grass", param1=255, param2=0},
|
{name="dirt_with_grass", param1=255, param2=0},
|
||||||
{name="ignore", param1=255, param2=0},
|
|
||||||
{name="air", param1=255, param2=0},
|
|
||||||
...
|
...
|
||||||
},
|
},
|
||||||
yslice_prob = {
|
yslice_prob = {
|
||||||
|
@ -3207,7 +3150,7 @@ Definition tables
|
||||||
},
|
},
|
||||||
-- ^ See 'Schematic specifier' for details.
|
-- ^ See 'Schematic specifier' for details.
|
||||||
replacements = {["oldname"] = "convert_to", ...},
|
replacements = {["oldname"] = "convert_to", ...},
|
||||||
flags = "place_center_x, place_center_y, place_center_z, force_placement",
|
flags = "place_center_x, place_center_z",
|
||||||
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
|
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
|
||||||
rotation = "90" -- rotate schematic 90 degrees on placement
|
rotation = "90" -- rotate schematic 90 degrees on placement
|
||||||
-- ^ Rotation can be "0", "90", "180", "270", or "random".
|
-- ^ Rotation can be "0", "90", "180", "270", or "random".
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Minetest Lua Mainmenu API Reference 0.4.12
|
Minetest Lua Mainmenu API Reference 0.4.11
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
|
@ -197,11 +197,9 @@ core.delete_world(index)
|
||||||
Helpers:
|
Helpers:
|
||||||
core.gettext(string) -> string
|
core.gettext(string) -> string
|
||||||
^ look up the translation of a string in the gettext message catalog
|
^ look up the translation of a string in the gettext message catalog
|
||||||
fgettext_ne(string, ...)
|
|
||||||
^ call core.gettext(string), replace "$1"..."$9" with the given
|
|
||||||
^ extra arguments and return the result
|
|
||||||
fgettext(string, ...) -> string
|
fgettext(string, ...) -> string
|
||||||
^ same as fgettext_ne(), but calls core.formspec_escape before returning result
|
^ call core.gettext(string), replace "$1"..."$9" with the given
|
||||||
|
^ extra arguments, call core.formspec_escape and return the result
|
||||||
core.parse_json(string[, nullvalue]) -> something (possible in async calls)
|
core.parse_json(string[, nullvalue]) -> something (possible in async calls)
|
||||||
^ see core.parse_json (lua_api.txt)
|
^ see core.parse_json (lua_api.txt)
|
||||||
dump(obj, dumped={})
|
dump(obj, dumped={})
|
||||||
|
@ -213,12 +211,6 @@ string:trim()
|
||||||
core.is_yes(arg) (possible in async calls)
|
core.is_yes(arg) (possible in async calls)
|
||||||
^ returns whether arg can be interpreted as yes
|
^ returns whether arg can be interpreted as yes
|
||||||
|
|
||||||
Version compat:
|
|
||||||
core.get_min_supp_proto()
|
|
||||||
^ returns the minimum supported network protocol version
|
|
||||||
core.get_max_supp_proto()
|
|
||||||
^ returns the maximum supported network protocol version
|
|
||||||
|
|
||||||
Async:
|
Async:
|
||||||
core.handle_async(async_job,parameters,finished)
|
core.handle_async(async_job,parameters,finished)
|
||||||
^ execute a function asynchronously
|
^ execute a function asynchronously
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#keymap_rangeselect = KEY_KEY_R
|
#keymap_rangeselect = KEY_KEY_R
|
||||||
#keymap_freemove = KEY_KEY_K
|
#keymap_freemove = KEY_KEY_K
|
||||||
#keymap_fastmove = KEY_KEY_J
|
#keymap_fastmove = KEY_KEY_J
|
||||||
#keymap_cinematic = KEY_F8
|
|
||||||
#keymap_screenshot = KEY_F12
|
#keymap_screenshot = KEY_F12
|
||||||
# If true, keymap_special1 instead of keymap_sneak is used for climbing down and descending
|
# If true, keymap_special1 instead of keymap_sneak is used for climbing down and descending
|
||||||
#aux1_descends = false
|
#aux1_descends = false
|
||||||
|
@ -128,13 +127,6 @@
|
||||||
#free_move = false
|
#free_move = false
|
||||||
# Continuous forward movement (for testing)
|
# Continuous forward movement (for testing)
|
||||||
#continuous_forward = false
|
#continuous_forward = false
|
||||||
# Enable cinematic mode
|
|
||||||
#cinematic = false
|
|
||||||
# Camera smoothing - smooths rotation of camera. 0 is no smoothing.
|
|
||||||
# Must be equal to or greater than 0, and less than 1.
|
|
||||||
#camera_smoothing = 0.0
|
|
||||||
# Camera smoothing when in cinematic mode
|
|
||||||
#cinematic_camera_smoothing = 0.7
|
|
||||||
# Fast movement (keymap_special1)
|
# Fast movement (keymap_special1)
|
||||||
#fast_move = false
|
#fast_move = false
|
||||||
# Invert mouse
|
# Invert mouse
|
||||||
|
@ -260,16 +252,16 @@
|
||||||
#freetype = true
|
#freetype = true
|
||||||
# Path to TrueTypeFont or bitmap
|
# Path to TrueTypeFont or bitmap
|
||||||
#font_path = fonts/liberationsans.ttf
|
#font_path = fonts/liberationsans.ttf
|
||||||
#font_size = 15
|
#font_size = 13
|
||||||
# Font shadow offset, if 0 then shadow will not be drawn
|
# Font shadow offset, if 0 then shadow will not be drawn
|
||||||
#font_shadow = 1
|
#font_shadow = 1
|
||||||
# Font shadow alpha (opaqueness, between 0 and 255)
|
# Font shadow alpha (opaqueness, between 0 and 255)
|
||||||
#font_shadow_alpha = 128
|
#font_shadow_alpha = 128
|
||||||
#mono_font_path = fonts/liberationmono.ttf
|
#mono_font_path = fonts/liberationmono.ttf
|
||||||
#mono_font_size = 15
|
#mono_font_size = 13
|
||||||
# This font will be used for certain languages
|
# This font will be used for certain languages
|
||||||
#fallback_font_path = fonts/DroidSansFallbackFull.ttf
|
#fallback_font_path = fonts/DroidSansFallbackFull.ttf
|
||||||
#fallback_font_size = 15
|
#fallback_font_size = 13
|
||||||
#fallback_font_shadow = 1
|
#fallback_font_shadow = 1
|
||||||
#fallback_font_shadow_alpha = 128
|
#fallback_font_shadow_alpha = 128
|
||||||
# Override language. When no value is provided (default) system language is used.
|
# Override language. When no value is provided (default) system language is used.
|
||||||
|
@ -345,7 +337,6 @@
|
||||||
# If true, disable cheat prevention in multiplayer
|
# If true, disable cheat prevention in multiplayer
|
||||||
#disable_anticheat = false
|
#disable_anticheat = false
|
||||||
# If true, actions are recorded for rollback
|
# If true, actions are recorded for rollback
|
||||||
# This option is only read when server starts
|
|
||||||
#enable_rollback_recording = false
|
#enable_rollback_recording = false
|
||||||
# Handling for deprecated lua api calls:
|
# Handling for deprecated lua api calls:
|
||||||
# "legacy" = (try to) mimic old behaviour (default for release).
|
# "legacy" = (try to) mimic old behaviour (default for release).
|
||||||
|
@ -469,8 +460,6 @@
|
||||||
# Controls size of deserts and beaches in Mapgen V6
|
# Controls size of deserts and beaches in Mapgen V6
|
||||||
#mgv6_freq_desert = 0.45
|
#mgv6_freq_desert = 0.45
|
||||||
#mgv6_freq_beach = 0.15
|
#mgv6_freq_beach = 0.15
|
||||||
# Enable/disable floating dungeons and dungeon slices
|
|
||||||
#enable_floating_dungeons = true
|
|
||||||
|
|
||||||
# Perlin noise attributes for different map generation parameters.
|
# Perlin noise attributes for different map generation parameters.
|
||||||
# Noise parameters can be specified as a set of positional values:
|
# Noise parameters can be specified as a set of positional values:
|
||||||
|
@ -488,14 +477,33 @@
|
||||||
# flags = "defaults"
|
# flags = "defaults"
|
||||||
#}
|
#}
|
||||||
# Only the group format supports noise flags which are needed for eased noise.
|
# Only the group format supports noise flags which are needed for eased noise.
|
||||||
# Mgv5 uses eased noise for np_ground so this is shown in group format,
|
# Mgv5 uses eased noise for np_cave1, np_cave2, np_ground and np_crumble, so these are shown in
|
||||||
# other noise parameters are shown in positional format to save space.
|
# group format, other noise parameters are shown in positional format to save space.
|
||||||
|
|
||||||
|
#mgv5_spflags = blobs
|
||||||
#mgv5_np_filler_depth = 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
|
#mgv5_np_filler_depth = 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
|
||||||
#mgv5_np_factor = 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
|
#mgv5_np_factor = 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
|
||||||
#mgv5_np_height = 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
|
#mgv5_np_height = 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
|
||||||
#mgv5_np_cave1 = 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
|
#mgv5_np_cave1 = {
|
||||||
#mgv5_np_cave2 = 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
|
# offset = 0
|
||||||
|
# scale = 6
|
||||||
|
# spread = (50, 50, 50)
|
||||||
|
# seed = 52534
|
||||||
|
# octaves = 4
|
||||||
|
# persistence = 0.5
|
||||||
|
# lacunarity = 2.0
|
||||||
|
# flags = "eased"
|
||||||
|
#}
|
||||||
|
#mgv5_np_cave2 = {
|
||||||
|
# offset = 0
|
||||||
|
# scale = 6
|
||||||
|
# spread = (50, 50, 50)
|
||||||
|
# seed = 10325
|
||||||
|
# octaves = 4
|
||||||
|
# persistence = 0.5
|
||||||
|
# lacunarity = 2.0
|
||||||
|
# flags = "eased"
|
||||||
|
#}
|
||||||
#mgv5_np_ground = {
|
#mgv5_np_ground = {
|
||||||
# offset = 0
|
# offset = 0
|
||||||
# scale = 40
|
# scale = 40
|
||||||
|
@ -506,6 +514,17 @@
|
||||||
# lacunarity = 2.0
|
# lacunarity = 2.0
|
||||||
# flags = "eased"
|
# flags = "eased"
|
||||||
#}
|
#}
|
||||||
|
#mgv5_np_crumble = {
|
||||||
|
# offset = 0
|
||||||
|
# scale = 1
|
||||||
|
# spread = (20, 20, 20)
|
||||||
|
# seed = 34413
|
||||||
|
# octaves = 3
|
||||||
|
# persistence = 1.3
|
||||||
|
# lacunarity = 2.0
|
||||||
|
# flags = "eased"
|
||||||
|
#}
|
||||||
|
#mgv5_np_wetness = 0, 1, (40, 40, 40), 32474, 4, 1.1, 2.0
|
||||||
|
|
||||||
#mgv6_spflags = biomeblend, jungles, mudflow
|
#mgv6_spflags = biomeblend, jungles, mudflow
|
||||||
#mgv6_np_terrain_base = -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
#mgv6_np_terrain_base = -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
Name=Minetest
|
Name=Minetest
|
||||||
GenericName=Minetest
|
GenericName=Minetest
|
||||||
Comment=Multiplayer infinite-world block sandbox
|
Comment=Multiplayer infinite-world block sandbox
|
||||||
Comment[fr]=Jeu multijoueurs de type bac à sable avec des mondes infinis
|
|
||||||
Comment[de]=Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten
|
|
||||||
Exec=minetest
|
Exec=minetest
|
||||||
Icon=minetest-icon
|
Icon=minetest-icon
|
||||||
Terminal=false
|
Terminal=false
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,18 +7,18 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: minetest\n"
|
"Project-Id-Version: minetest\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2015-02-14 13:50+0100\n"
|
"POT-Creation-Date: 2014-12-13 15:24+0100\n"
|
||||||
"PO-Revision-Date: 2015-02-14 13:35+0100\n"
|
"PO-Revision-Date: 2015-01-19 09:56+0100\n"
|
||||||
"Last-Translator: Diego de las Heras <diegodelasheras@gmail.com>\n"
|
"Last-Translator: Diego de las Heras <diegodelasheras@gmail.com>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Poedit 1.7.4\n"
|
"X-Generator: Poedit 1.7.3\n"
|
||||||
|
|
||||||
#: builtin/fstk/ui.lua:67 builtin/mainmenu/store.lua:165
|
#: builtin/fstk/ui.lua:67
|
||||||
msgid "Ok"
|
msgid "Ok"
|
||||||
msgstr "Aceptar"
|
msgstr "Aceptar"
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ msgstr "Ocultar contenido mp"
|
||||||
msgid "Mod:"
|
msgid "Mod:"
|
||||||
msgstr "Mod:"
|
msgstr "Mod:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua:48 builtin/mainmenu/tab_mods.lua:99
|
#: builtin/mainmenu/dlg_config_world.lua:48
|
||||||
msgid "Depends:"
|
msgid "Depends:"
|
||||||
msgstr "Dependencias:"
|
msgstr "Dependencias:"
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ msgstr "¿Realmente desea borrar \"$1\"?"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_delete_mod.lua:27
|
#: builtin/mainmenu/dlg_delete_mod.lua:27
|
||||||
#: builtin/mainmenu/dlg_delete_world.lua:25
|
#: builtin/mainmenu/dlg_delete_world.lua:25
|
||||||
#: builtin/mainmenu/tab_settings.lua:79
|
#: builtin/mainmenu/tab_settings.lua:25
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr "Sí"
|
msgstr "Sí"
|
||||||
|
|
||||||
|
@ -186,40 +186,48 @@ msgstr "Instalar mod: Imposible encontrar el nombre real del mod para: $1"
|
||||||
msgid "Unsorted"
|
msgid "Unsorted"
|
||||||
msgstr "Sin ordenar"
|
msgstr "Sin ordenar"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:99 builtin/mainmenu/store.lua:580
|
#: builtin/mainmenu/store.lua:99 builtin/mainmenu/store.lua:584
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Buscar"
|
msgstr "Buscar"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:126
|
#: builtin/mainmenu/store.lua:125
|
||||||
msgid "Downloading $1, please wait..."
|
msgid "Downloading"
|
||||||
msgstr "Descargando $1, por favor espere..."
|
msgstr "Descargando"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:160
|
#: builtin/mainmenu/store.lua:127
|
||||||
|
msgid "please wait..."
|
||||||
|
msgstr "por favor espere..."
|
||||||
|
|
||||||
|
#: builtin/mainmenu/store.lua:159
|
||||||
msgid "Successfully installed:"
|
msgid "Successfully installed:"
|
||||||
msgstr "Instalado con éxito:"
|
msgstr "Instalado con éxito:"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:162
|
#: builtin/mainmenu/store.lua:163
|
||||||
msgid "Shortname:"
|
msgid "Shortname:"
|
||||||
msgstr "Nombre corto:"
|
msgstr "Nombre corto:"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:472
|
#: builtin/mainmenu/store.lua:167 src/guiFormSpecMenu.cpp:2866
|
||||||
|
msgid "ok"
|
||||||
|
msgstr "aceptar"
|
||||||
|
|
||||||
|
#: builtin/mainmenu/store.lua:476
|
||||||
msgid "Rating"
|
msgid "Rating"
|
||||||
msgstr "Clasificación"
|
msgstr "Clasificación"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:497
|
#: builtin/mainmenu/store.lua:501
|
||||||
msgid "re-Install"
|
msgid "re-Install"
|
||||||
msgstr "Reinstalar"
|
msgstr "Reinstalar"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:499
|
#: builtin/mainmenu/store.lua:503
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Instalar"
|
msgstr "Instalar"
|
||||||
|
|
||||||
# En el menú principal de mods pone repositorio no tienda.
|
# En el menú principal de mods pone repositorio no tienda.
|
||||||
#: builtin/mainmenu/store.lua:518
|
#: builtin/mainmenu/store.lua:522
|
||||||
msgid "Close store"
|
msgid "Close store"
|
||||||
msgstr "Cerrar repositorio"
|
msgstr "Cerrar repositorio"
|
||||||
|
|
||||||
#: builtin/mainmenu/store.lua:526
|
#: builtin/mainmenu/store.lua:530
|
||||||
msgid "Page $1 of $2"
|
msgid "Page $1 of $2"
|
||||||
msgstr "Página $1 de $2"
|
msgstr "Página $1 de $2"
|
||||||
|
|
||||||
|
@ -280,7 +288,8 @@ msgstr "Mods"
|
||||||
msgid "Address / Port :"
|
msgid "Address / Port :"
|
||||||
msgstr "Dirección / puerto:"
|
msgstr "Dirección / puerto:"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_multiplayer.lua:24
|
#: builtin/mainmenu/tab_multiplayer.lua:24 builtin/mainmenu/tab_server.lua:37
|
||||||
|
#: builtin/mainmenu/tab_simple_main.lua:25
|
||||||
msgid "Name / Password :"
|
msgid "Name / Password :"
|
||||||
msgstr "Nombre / contraseña:"
|
msgstr "Nombre / contraseña:"
|
||||||
|
|
||||||
|
@ -299,22 +308,7 @@ msgstr "Borrar"
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "Conectar"
|
msgstr "Conectar"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_multiplayer.lua:62
|
#: builtin/mainmenu/tab_multiplayer.lua:252
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:45
|
|
||||||
msgid "Creative mode"
|
|
||||||
msgstr "Modo creativo"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_multiplayer.lua:63
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:46
|
|
||||||
msgid "Damage enabled"
|
|
||||||
msgstr "Daño activado"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_multiplayer.lua:64
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:47
|
|
||||||
msgid "PvP enabled"
|
|
||||||
msgstr "PvP activado"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_multiplayer.lua:247
|
|
||||||
msgid "Client"
|
msgid "Client"
|
||||||
msgstr "Cliente"
|
msgstr "Cliente"
|
||||||
|
|
||||||
|
@ -334,12 +328,12 @@ msgstr "Iniciar juego"
|
||||||
msgid "Select World:"
|
msgid "Select World:"
|
||||||
msgstr "Selecciona un mundo:"
|
msgstr "Selecciona un mundo:"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_server.lua:31 builtin/mainmenu/tab_simple_main.lua:75
|
#: builtin/mainmenu/tab_server.lua:31 builtin/mainmenu/tab_simple_main.lua:63
|
||||||
#: builtin/mainmenu/tab_singleplayer.lua:90
|
#: builtin/mainmenu/tab_singleplayer.lua:90
|
||||||
msgid "Creative Mode"
|
msgid "Creative Mode"
|
||||||
msgstr "Modo creativo"
|
msgstr "Modo creativo"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_server.lua:33 builtin/mainmenu/tab_simple_main.lua:77
|
#: builtin/mainmenu/tab_server.lua:33 builtin/mainmenu/tab_simple_main.lua:65
|
||||||
#: builtin/mainmenu/tab_singleplayer.lua:92
|
#: builtin/mainmenu/tab_singleplayer.lua:92
|
||||||
msgid "Enable Damage"
|
msgid "Enable Damage"
|
||||||
msgstr "Permitir daños"
|
msgstr "Permitir daños"
|
||||||
|
@ -348,11 +342,6 @@ msgstr "Permitir daños"
|
||||||
msgid "Public"
|
msgid "Public"
|
||||||
msgstr "Público"
|
msgstr "Público"
|
||||||
|
|
||||||
# Los dos puntos son intencionados.
|
|
||||||
#: builtin/mainmenu/tab_server.lua:37 builtin/mainmenu/tab_simple_main.lua:25
|
|
||||||
msgid "Name/Password"
|
|
||||||
msgstr "Nombre / contraseña:"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_server.lua:45
|
#: builtin/mainmenu/tab_server.lua:45
|
||||||
msgid "Bind Address"
|
msgid "Bind Address"
|
||||||
msgstr "Asociar dirección"
|
msgstr "Asociar dirección"
|
||||||
|
@ -369,151 +358,133 @@ msgstr "Puerto del servidor:"
|
||||||
msgid "Server"
|
msgid "Server"
|
||||||
msgstr "Servidor"
|
msgstr "Servidor"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:21
|
|
||||||
msgid "No Filter"
|
|
||||||
msgstr "Sin filtro"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:22
|
|
||||||
msgid "Bilinear Filter"
|
|
||||||
msgstr "Filtro bi-lineal"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:23
|
#: builtin/mainmenu/tab_settings.lua:23
|
||||||
msgid "Trilinear Filter"
|
|
||||||
msgstr "Filtro tri-lineal"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:32
|
|
||||||
msgid "No Mipmap"
|
|
||||||
msgstr "Sin Mipmap"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:33
|
|
||||||
msgid "Mipmap"
|
|
||||||
msgstr "Mipmap"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:34
|
|
||||||
msgid "Mipmap + Aniso. Filter"
|
|
||||||
msgstr "Mipmap + Filtro aniso."
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:77
|
|
||||||
msgid "Are you sure to reset your singleplayer world?"
|
msgid "Are you sure to reset your singleplayer world?"
|
||||||
msgstr "¿Estás seguro de querer reiniciar el mundo de un jugador?"
|
msgstr "¿Estás seguro de querer reiniciar el mundo de un jugador?"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:81
|
#: builtin/mainmenu/tab_settings.lua:27
|
||||||
msgid "No!!!"
|
msgid "No!!!"
|
||||||
msgstr "¡¡¡No!!!"
|
msgstr "¡¡¡No!!!"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:181
|
#: builtin/mainmenu/tab_settings.lua:134
|
||||||
msgid "Smooth Lighting"
|
msgid "Smooth Lighting"
|
||||||
msgstr "Iluminación suave"
|
msgstr "Iluminación suave"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:183
|
#: builtin/mainmenu/tab_settings.lua:136
|
||||||
msgid "Enable Particles"
|
msgid "Enable Particles"
|
||||||
msgstr "Habilitar partículas"
|
msgstr "Habilitar partículas"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:185
|
#: builtin/mainmenu/tab_settings.lua:138
|
||||||
msgid "3D Clouds"
|
msgid "3D Clouds"
|
||||||
msgstr "Nubes 3D"
|
msgstr "Nubes 3D"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:187
|
#: builtin/mainmenu/tab_settings.lua:141
|
||||||
msgid "Fancy Trees"
|
msgid "Fancy Trees"
|
||||||
msgstr "Árboles detallados"
|
msgstr "Árboles detallados"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:189
|
#: builtin/mainmenu/tab_settings.lua:142
|
||||||
msgid "Opaque Water"
|
msgid "Opaque Water"
|
||||||
msgstr "Agua opaca"
|
msgstr "Agua opaca"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:191
|
#: builtin/mainmenu/tab_settings.lua:145
|
||||||
msgid "Connected Glass"
|
msgid "Connected Glass"
|
||||||
msgstr "Vidrios conectados"
|
msgstr "Vidrios conectados"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:193
|
#: builtin/mainmenu/tab_settings.lua:149
|
||||||
msgid "Node Highlighting"
|
|
||||||
msgstr "Resaltar nodos"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:196
|
|
||||||
msgid "Texturing:"
|
|
||||||
msgstr "Texturizado:"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:201
|
|
||||||
msgid "Rendering:"
|
|
||||||
msgstr "Renderizado:"
|
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:205
|
|
||||||
msgid "Restart minetest for driver change to take effect"
|
msgid "Restart minetest for driver change to take effect"
|
||||||
msgstr "Reinicia minetest para que los cambios en el controlador tengan efecto"
|
msgstr "Reinicia minetest para que los cambios en el controlador tengan efecto"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:207
|
#: builtin/mainmenu/tab_settings.lua:151
|
||||||
|
msgid "Mip-Mapping"
|
||||||
|
msgstr "Mip-Mapping"
|
||||||
|
|
||||||
|
#: builtin/mainmenu/tab_settings.lua:153
|
||||||
|
msgid "Anisotropic Filtering"
|
||||||
|
msgstr "Filtrado Anisotrópico"
|
||||||
|
|
||||||
|
#: builtin/mainmenu/tab_settings.lua:155
|
||||||
|
msgid "Bi-Linear Filtering"
|
||||||
|
msgstr "Filtrado Bi-Lineal"
|
||||||
|
|
||||||
|
#: builtin/mainmenu/tab_settings.lua:157
|
||||||
|
msgid "Tri-Linear Filtering"
|
||||||
|
msgstr "Filtrado Tri-Lineal"
|
||||||
|
|
||||||
|
#: builtin/mainmenu/tab_settings.lua:160
|
||||||
msgid "Shaders"
|
msgid "Shaders"
|
||||||
msgstr "Sombreadores"
|
msgstr "Sombreadores"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:212
|
#: builtin/mainmenu/tab_settings.lua:164
|
||||||
msgid "Change keys"
|
msgid "Change keys"
|
||||||
msgstr "Configurar teclas"
|
msgstr "Configurar teclas"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:215
|
#: builtin/mainmenu/tab_settings.lua:167
|
||||||
msgid "Reset singleplayer world"
|
msgid "Reset singleplayer world"
|
||||||
msgstr "Reiniciar mundo de un jugador"
|
msgstr "Reiniciar mundo de un jugador"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:219
|
#: builtin/mainmenu/tab_settings.lua:171
|
||||||
msgid "GUI scale factor"
|
msgid "GUI scale factor"
|
||||||
msgstr "Factor de escala (GUI)"
|
msgstr "Factor de escala (GUI)"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:223
|
#: builtin/mainmenu/tab_settings.lua:175
|
||||||
msgid "Scaling factor applied to menu elements: "
|
msgid "Scaling factor applied to menu elements: "
|
||||||
msgstr "Factor de escala aplicado a los elementos del menú: "
|
msgstr "Factor de escala aplicado a los elementos del menú: "
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:229
|
#: builtin/mainmenu/tab_settings.lua:182
|
||||||
|
#, fuzzy
|
||||||
msgid "Touch free target"
|
msgid "Touch free target"
|
||||||
msgstr "Tocar para interactuar"
|
msgstr "Tocar para interactuar"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:235
|
#: builtin/mainmenu/tab_settings.lua:187
|
||||||
msgid "Touchthreshold (px)"
|
msgid "Touchthreshold (px)"
|
||||||
msgstr "Umbral táctil (px)"
|
msgstr "Umbral táctil (px)"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:242 builtin/mainmenu/tab_settings.lua:256
|
#: builtin/mainmenu/tab_settings.lua:194 builtin/mainmenu/tab_settings.lua:208
|
||||||
|
#, fuzzy
|
||||||
msgid "Bumpmapping"
|
msgid "Bumpmapping"
|
||||||
msgstr "Mapeado de relieve"
|
msgstr "Mapeado de relieve"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:244 builtin/mainmenu/tab_settings.lua:257
|
#: builtin/mainmenu/tab_settings.lua:196 builtin/mainmenu/tab_settings.lua:209
|
||||||
msgid "Generate Normalmaps"
|
msgid "Generate Normalmaps"
|
||||||
msgstr "Generar mapas normales"
|
msgstr "Generar mapas normales"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:246 builtin/mainmenu/tab_settings.lua:258
|
#: builtin/mainmenu/tab_settings.lua:198 builtin/mainmenu/tab_settings.lua:210
|
||||||
msgid "Parallax Occlusion"
|
msgid "Parallax Occlusion"
|
||||||
msgstr "Oclusión de paralaje"
|
msgstr "Oclusión de paralaje"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:248 builtin/mainmenu/tab_settings.lua:259
|
#: builtin/mainmenu/tab_settings.lua:200 builtin/mainmenu/tab_settings.lua:211
|
||||||
msgid "Waving Water"
|
msgid "Waving Water"
|
||||||
msgstr "Oleaje en el agua"
|
msgstr "Oleaje en el agua"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:250 builtin/mainmenu/tab_settings.lua:260
|
#: builtin/mainmenu/tab_settings.lua:202 builtin/mainmenu/tab_settings.lua:212
|
||||||
msgid "Waving Leaves"
|
msgid "Waving Leaves"
|
||||||
msgstr "Movimiento de hojas"
|
msgstr "Movimiento de hojas"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:252 builtin/mainmenu/tab_settings.lua:261
|
#: builtin/mainmenu/tab_settings.lua:204 builtin/mainmenu/tab_settings.lua:213
|
||||||
msgid "Waving Plants"
|
msgid "Waving Plants"
|
||||||
msgstr "Movimiento de plantas"
|
msgstr "Movimiento de plantas"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:287
|
#: builtin/mainmenu/tab_settings.lua:255
|
||||||
msgid "To enable shaders the OpenGL driver needs to be used."
|
msgid "To enable shaders the OpenGL driver needs to be used."
|
||||||
msgstr "Para habilitar los sombreadores debe utilizar el controlador OpenGL."
|
msgstr "Para habilitar los sombreadores debe utilizar el controlador OpenGL."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_settings.lua:398
|
#: builtin/mainmenu/tab_settings.lua:330
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:79
|
#: builtin/mainmenu/tab_simple_main.lua:67
|
||||||
msgid "Fly mode"
|
msgid "Fly mode"
|
||||||
msgstr "Modo vuelo"
|
msgstr "Modo vuelo"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:83
|
#: builtin/mainmenu/tab_simple_main.lua:71
|
||||||
msgid "Start Singleplayer"
|
msgid "Start Singleplayer"
|
||||||
msgstr "Comenzar un jugador"
|
msgstr "Comenzar un jugador"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:84
|
#: builtin/mainmenu/tab_simple_main.lua:72
|
||||||
msgid "Config mods"
|
msgid "Config mods"
|
||||||
msgstr "Configurar mods"
|
msgstr "Configurar mods"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_simple_main.lua:203
|
#: builtin/mainmenu/tab_simple_main.lua:191
|
||||||
msgid "Main"
|
msgid "Main"
|
||||||
msgstr "Principal"
|
msgstr "Principal"
|
||||||
|
|
||||||
|
@ -538,195 +509,39 @@ msgstr "Sin información disponible"
|
||||||
msgid "Texturepacks"
|
msgid "Texturepacks"
|
||||||
msgstr "Texturas"
|
msgstr "Texturas"
|
||||||
|
|
||||||
#: src/client.cpp:2788
|
#: src/client.cpp:2726
|
||||||
msgid "Loading textures..."
|
|
||||||
msgstr "Cargando texturas..."
|
|
||||||
|
|
||||||
#: src/client.cpp:2798
|
|
||||||
msgid "Rebuilding shaders..."
|
|
||||||
msgstr "Reconstruyendo sombreadores..."
|
|
||||||
|
|
||||||
#: src/client.cpp:2805
|
|
||||||
msgid "Initializing nodes..."
|
|
||||||
msgstr "Inicializando nodos..."
|
|
||||||
|
|
||||||
#: src/client.cpp:2820
|
|
||||||
msgid "Item textures..."
|
msgid "Item textures..."
|
||||||
msgstr "Texturas de objetos..."
|
msgstr "Texturas de objetos..."
|
||||||
|
|
||||||
#: src/client.cpp:2845
|
|
||||||
msgid "Done!"
|
|
||||||
msgstr "¡Completado!"
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:171
|
|
||||||
msgid "Main Menu"
|
|
||||||
msgstr "Menú principal"
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:209
|
|
||||||
msgid "Player name too long."
|
|
||||||
msgstr "Nombre de jugador demasiado largo."
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:247
|
|
||||||
msgid "Connection error (timed out?)"
|
|
||||||
msgstr "Error de conexión (¿tiempo agotado?)"
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:412
|
|
||||||
msgid "No world selected and no address provided. Nothing to do."
|
|
||||||
msgstr ""
|
|
||||||
"No se seleccionó el mundo y no se ha especificado una dirección. Nada que "
|
|
||||||
"hacer."
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:419
|
|
||||||
msgid "Provided world path doesn't exist: "
|
|
||||||
msgstr "La ruta del mundo especificada no existe: "
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:428
|
|
||||||
msgid "Could not find or load game \""
|
|
||||||
msgstr "No se puede encontrar o cargar el juego \""
|
|
||||||
|
|
||||||
#: src/client/clientlauncher.cpp:446
|
|
||||||
msgid "Invalid gamespec."
|
|
||||||
msgstr "Juego especificado no válido."
|
|
||||||
|
|
||||||
#: src/fontengine.cpp:70 src/fontengine.cpp:226
|
#: src/fontengine.cpp:70 src/fontengine.cpp:226
|
||||||
msgid "needs_fallback_font"
|
msgid "needs_fallback_font"
|
||||||
msgstr "needs_fallback_font"
|
msgstr "needs_fallback_font"
|
||||||
|
|
||||||
#: src/game.cpp:1057 src/guiFormSpecMenu.cpp:2006
|
#: src/game.cpp:1063
|
||||||
msgid "Proceed"
|
|
||||||
msgstr "Continuar"
|
|
||||||
|
|
||||||
#: src/game.cpp:1077
|
|
||||||
msgid "You died."
|
|
||||||
msgstr "Has muerto."
|
|
||||||
|
|
||||||
#: src/game.cpp:1078
|
|
||||||
msgid "Respawn"
|
msgid "Respawn"
|
||||||
msgstr "Revivir"
|
msgstr "Revivir"
|
||||||
|
|
||||||
#: src/game.cpp:1097
|
#: src/game.cpp:2250
|
||||||
msgid ""
|
|
||||||
"Default Controls:\n"
|
|
||||||
"No menu visible:\n"
|
|
||||||
"- single tap: button activate\n"
|
|
||||||
"- double tap: place/use\n"
|
|
||||||
"- slide finger: look around\n"
|
|
||||||
"Menu/Inventory visible:\n"
|
|
||||||
"- double tap (outside):\n"
|
|
||||||
" -->close\n"
|
|
||||||
"- touch stack, touch slot:\n"
|
|
||||||
" --> move stack\n"
|
|
||||||
"- touch&drag, tap 2nd finger\n"
|
|
||||||
" --> place single item to slot\n"
|
|
||||||
msgstr ""
|
|
||||||
"Controles predeterminados:\n"
|
|
||||||
"Con el menú oculto:\n"
|
|
||||||
"- toque simple: botón activar\n"
|
|
||||||
"- toque doble: colocar/usar\n"
|
|
||||||
"- deslizar dedo: mirar alrededor\n"
|
|
||||||
"Con el menú/inventario visible:\n"
|
|
||||||
"- toque doble (fuera):\n"
|
|
||||||
" -->cerrar\n"
|
|
||||||
"- toque en la pila de objetos:\n"
|
|
||||||
" -->mover la pila\n"
|
|
||||||
"- toque y arrastrar, toque con 2 dedos:\n"
|
|
||||||
" -->colocar solamente un objeto\n"
|
|
||||||
|
|
||||||
#: src/game.cpp:1111
|
|
||||||
msgid ""
|
|
||||||
"Default Controls:\n"
|
|
||||||
"- WASD: move\n"
|
|
||||||
"- Space: jump/climb\n"
|
|
||||||
"- Shift: sneak/go down\n"
|
|
||||||
"- Q: drop item\n"
|
|
||||||
"- I: inventory\n"
|
|
||||||
"- Mouse: turn/look\n"
|
|
||||||
"- Mouse left: dig/punch\n"
|
|
||||||
"- Mouse right: place/use\n"
|
|
||||||
"- Mouse wheel: select item\n"
|
|
||||||
"- T: chat\n"
|
|
||||||
msgstr ""
|
|
||||||
"Controles predeterminados:\n"
|
|
||||||
"- WASD: moverse\n"
|
|
||||||
"- Espacio: saltar/subir\n"
|
|
||||||
"- Mayús.: puntillas/bajar\n"
|
|
||||||
"- Q: soltar objeto\n"
|
|
||||||
"- I: inventario\n"
|
|
||||||
"- Ratón: girar/mirar\n"
|
|
||||||
"- Ratón izq.: cavar/golpear\n"
|
|
||||||
"- Ratón der.: colocar/usar\n"
|
|
||||||
"- Ratón rueda: elegir objeto\n"
|
|
||||||
"- T: chat\n"
|
|
||||||
|
|
||||||
#: src/game.cpp:1130
|
|
||||||
msgid "Continue"
|
|
||||||
msgstr "Continuar"
|
|
||||||
|
|
||||||
#: src/game.cpp:1134
|
|
||||||
msgid "Change Password"
|
|
||||||
msgstr "Cambiar contraseña"
|
|
||||||
|
|
||||||
#: src/game.cpp:1139
|
|
||||||
msgid "Sound Volume"
|
|
||||||
msgstr "Volumen del sonido"
|
|
||||||
|
|
||||||
#: src/game.cpp:1141
|
|
||||||
msgid "Change Keys"
|
|
||||||
msgstr "Configurar teclas"
|
|
||||||
|
|
||||||
#: src/game.cpp:1144
|
|
||||||
msgid "Exit to Menu"
|
|
||||||
msgstr "Salir al menú"
|
|
||||||
|
|
||||||
#: src/game.cpp:1146
|
|
||||||
msgid "Exit to OS"
|
|
||||||
msgstr "Salir al S.O."
|
|
||||||
|
|
||||||
#: src/game.cpp:1809
|
|
||||||
msgid "Shutting down..."
|
|
||||||
msgstr "Cerrando..."
|
|
||||||
|
|
||||||
#: src/game.cpp:1858
|
|
||||||
msgid "Loading..."
|
|
||||||
msgstr "Cargando..."
|
|
||||||
|
|
||||||
#: src/game.cpp:1915
|
|
||||||
msgid "Creating server..."
|
|
||||||
msgstr "Creando servidor..."
|
|
||||||
|
|
||||||
#: src/game.cpp:1952
|
|
||||||
msgid "Creating client..."
|
|
||||||
msgstr "Creando cliente..."
|
|
||||||
|
|
||||||
#: src/game.cpp:2125
|
|
||||||
msgid "Resolving address..."
|
|
||||||
msgstr "Resolviendo dirección..."
|
|
||||||
|
|
||||||
#: src/game.cpp:2216
|
|
||||||
msgid "Connecting to server..."
|
|
||||||
msgstr "Conectando al servidor..."
|
|
||||||
|
|
||||||
#: src/game.cpp:2274
|
|
||||||
msgid "Item definitions..."
|
msgid "Item definitions..."
|
||||||
msgstr "Definiciones de objetos..."
|
msgstr "Definiciones de objetos..."
|
||||||
|
|
||||||
#: src/game.cpp:2279
|
#: src/game.cpp:2255
|
||||||
msgid "Node definitions..."
|
msgid "Node definitions..."
|
||||||
msgstr "Definiciones de nodos..."
|
msgstr "Definiciones de nodos..."
|
||||||
|
|
||||||
#: src/game.cpp:2286
|
#: src/game.cpp:2262
|
||||||
msgid "Media..."
|
msgid "Media..."
|
||||||
msgstr "Media..."
|
msgstr "Media..."
|
||||||
|
|
||||||
#: src/game.cpp:2291
|
#: src/game.cpp:2267
|
||||||
msgid " KB/s"
|
msgid " KB/s"
|
||||||
msgstr " KB/s"
|
msgstr " KB/s"
|
||||||
|
|
||||||
#: src/game.cpp:2295
|
#: src/game.cpp:2271
|
||||||
msgid " MB/s"
|
msgid " MB/s"
|
||||||
msgstr " MB/s"
|
msgstr " MB/s"
|
||||||
|
|
||||||
#: src/game.cpp:4210
|
#: src/game.cpp:4220
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"Check debug.txt for details."
|
"Check debug.txt for details."
|
||||||
|
@ -734,14 +549,14 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Consulta debug.txt para obtener más detalles."
|
"Consulta debug.txt para obtener más detalles."
|
||||||
|
|
||||||
#: src/guiFormSpecMenu.cpp:2797
|
#: src/guiFormSpecMenu.cpp:2055
|
||||||
|
msgid "Proceed"
|
||||||
|
msgstr "Continuar"
|
||||||
|
|
||||||
|
#: src/guiFormSpecMenu.cpp:2846
|
||||||
msgid "Enter "
|
msgid "Enter "
|
||||||
msgstr "Ingresar "
|
msgstr "Ingresar "
|
||||||
|
|
||||||
#: src/guiFormSpecMenu.cpp:2817
|
|
||||||
msgid "ok"
|
|
||||||
msgstr "aceptar"
|
|
||||||
|
|
||||||
#: src/guiKeyChangeMenu.cpp:125
|
#: src/guiKeyChangeMenu.cpp:125
|
||||||
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -832,23 +647,23 @@ msgstr "Seleccionar distancia"
|
||||||
msgid "Print stacks"
|
msgid "Print stacks"
|
||||||
msgstr "Imprimir pilas"
|
msgstr "Imprimir pilas"
|
||||||
|
|
||||||
#: src/guiPasswordChange.cpp:108
|
#: src/guiPasswordChange.cpp:106
|
||||||
msgid "Old Password"
|
msgid "Old Password"
|
||||||
msgstr "Contraseña anterior"
|
msgstr "Contraseña anterior"
|
||||||
|
|
||||||
#: src/guiPasswordChange.cpp:124
|
#: src/guiPasswordChange.cpp:122
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Contraseña nueva"
|
msgstr "Contraseña nueva"
|
||||||
|
|
||||||
#: src/guiPasswordChange.cpp:139
|
#: src/guiPasswordChange.cpp:137
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirmar contraseña"
|
msgstr "Confirmar contraseña"
|
||||||
|
|
||||||
#: src/guiPasswordChange.cpp:155
|
#: src/guiPasswordChange.cpp:153
|
||||||
msgid "Change"
|
msgid "Change"
|
||||||
msgstr "Cambiar"
|
msgstr "Cambiar"
|
||||||
|
|
||||||
#: src/guiPasswordChange.cpp:164
|
#: src/guiPasswordChange.cpp:162
|
||||||
msgid "Passwords do not match!"
|
msgid "Passwords do not match!"
|
||||||
msgstr "¡Las contraseñas no coinciden!"
|
msgstr "¡Las contraseñas no coinciden!"
|
||||||
|
|
||||||
|
@ -1148,3 +963,210 @@ msgstr "PA1"
|
||||||
#: src/keycode.cpp:249
|
#: src/keycode.cpp:249
|
||||||
msgid "Zoom"
|
msgid "Zoom"
|
||||||
msgstr "Zoom"
|
msgstr "Zoom"
|
||||||
|
|
||||||
|
#: src/main.cpp:1681
|
||||||
|
msgid "Main Menu"
|
||||||
|
msgstr "Menú principal"
|
||||||
|
|
||||||
|
#: src/main.cpp:1719
|
||||||
|
msgid "Player name too long."
|
||||||
|
msgstr "Nombre de jugador demasiado largo."
|
||||||
|
|
||||||
|
#: src/main.cpp:1757
|
||||||
|
msgid "Connection error (timed out?)"
|
||||||
|
msgstr "Error de conexión (¿tiempo agotado?)"
|
||||||
|
|
||||||
|
#: src/main.cpp:1919
|
||||||
|
msgid "No world selected and no address provided. Nothing to do."
|
||||||
|
msgstr ""
|
||||||
|
"No se seleccionó el mundo y no se ha especificado una dirección. Nada que "
|
||||||
|
"hacer."
|
||||||
|
|
||||||
|
#: src/main.cpp:1926
|
||||||
|
msgid "Provided world path doesn't exist: "
|
||||||
|
msgstr "La ruta del mundo especificada no existe: "
|
||||||
|
|
||||||
|
#: src/main.cpp:1935
|
||||||
|
msgid "Could not find or load game \""
|
||||||
|
msgstr "No se puede encontrar o cargar el juego \""
|
||||||
|
|
||||||
|
#: src/main.cpp:1953
|
||||||
|
msgid "Invalid gamespec."
|
||||||
|
msgstr "Juego especificado no válido."
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Default Controls:\n"
|
||||||
|
"- WASD: move\n"
|
||||||
|
"- Space: jump/climb\n"
|
||||||
|
"- Shift: sneak/go down\n"
|
||||||
|
"- Q: drop item\n"
|
||||||
|
"- I: inventory\n"
|
||||||
|
"- Mouse: turn/look\n"
|
||||||
|
"- Mouse left: dig/punch\n"
|
||||||
|
"- Mouse right: place/use\n"
|
||||||
|
"- Mouse wheel: select item\n"
|
||||||
|
"- T: chat\n"
|
||||||
|
msgstr ""
|
||||||
|
"Controles predeterminados:\n"
|
||||||
|
"- WASD: moverse\n"
|
||||||
|
"- Espacio: saltar/subir\n"
|
||||||
|
"- Mayús.: puntillas/bajar\n"
|
||||||
|
"- Q: soltar objeto\n"
|
||||||
|
"- I: inventario\n"
|
||||||
|
"- Ratón: girar/mirar\n"
|
||||||
|
"- Ratón izq.: cavar/golpear\n"
|
||||||
|
"- Ratón der.: colocar/usar\n"
|
||||||
|
"- Ratón rueda: elegir objeto\n"
|
||||||
|
"- T: chat\n"
|
||||||
|
|
||||||
|
msgid "is required by:"
|
||||||
|
msgstr "es requerido por:"
|
||||||
|
|
||||||
|
msgid "Configuration saved. "
|
||||||
|
msgstr "Configuración guardada. "
|
||||||
|
|
||||||
|
msgid "Warning: Configuration not consistent. "
|
||||||
|
msgstr "Advertencia: La configuración no es coherente."
|
||||||
|
|
||||||
|
msgid "Cannot create world: Name contains invalid characters"
|
||||||
|
msgstr "No se puede crear el mundo: El nombre contiene caracteres no válidos"
|
||||||
|
|
||||||
|
msgid "Multiplayer"
|
||||||
|
msgstr "Multijugador"
|
||||||
|
|
||||||
|
msgid "Advanced"
|
||||||
|
msgstr "Avanzado"
|
||||||
|
|
||||||
|
msgid "Show Public"
|
||||||
|
msgstr "Mostrar público"
|
||||||
|
|
||||||
|
msgid "Show Favorites"
|
||||||
|
msgstr "Mostrar favoritos"
|
||||||
|
|
||||||
|
msgid "Leave address blank to start a local server."
|
||||||
|
msgstr "Dejar la dirección en blanco para iniciar un servidor local."
|
||||||
|
|
||||||
|
msgid "Address required."
|
||||||
|
msgstr "Requiere una dirección."
|
||||||
|
|
||||||
|
msgid "Cannot delete world: Nothing selected"
|
||||||
|
msgstr "No se puede eliminar el mundo: Ninguno seleccionado"
|
||||||
|
|
||||||
|
msgid "Files to be deleted"
|
||||||
|
msgstr "Archivos que se eliminarán"
|
||||||
|
|
||||||
|
msgid "Cannot create world: No games found"
|
||||||
|
msgstr "No se puede crear el mundo: No se encontraron juegos"
|
||||||
|
|
||||||
|
msgid "Cannot configure world: Nothing selected"
|
||||||
|
msgstr "No se puede configurar el mundo: Ninguno seleccionado"
|
||||||
|
|
||||||
|
msgid "Failed to delete all world files"
|
||||||
|
msgstr "No se pudo eliminar todos los archivos del mundo"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Warning: Some configured mods are missing.\n"
|
||||||
|
"Their setting will be removed when you save the configuration. "
|
||||||
|
msgstr ""
|
||||||
|
"Advertencia: Algunos mods configurados faltan.\n"
|
||||||
|
"Sus ajustes se eliminarán al guardar la configuración. "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Warning: Some mods are not configured yet.\n"
|
||||||
|
"They will be enabled by default when you save the configuration. "
|
||||||
|
msgstr ""
|
||||||
|
"Advertencia: Algunos mods todavía no están configurados.\n"
|
||||||
|
"Se habilitarán de forma predeterminada al guardar la configuración. "
|
||||||
|
|
||||||
|
msgid "Exit to OS"
|
||||||
|
msgstr "Salir al S.O."
|
||||||
|
|
||||||
|
msgid "Exit to Menu"
|
||||||
|
msgstr "Salir al menú"
|
||||||
|
|
||||||
|
msgid "Sound Volume"
|
||||||
|
msgstr "Volumen del sonido"
|
||||||
|
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr "Cambiar contraseña"
|
||||||
|
|
||||||
|
msgid "Continue"
|
||||||
|
msgstr "Continuar"
|
||||||
|
|
||||||
|
msgid "You died."
|
||||||
|
msgstr "Has muerto."
|
||||||
|
|
||||||
|
msgid "Shutting down..."
|
||||||
|
msgstr "Cerrando..."
|
||||||
|
|
||||||
|
msgid "Connecting to server..."
|
||||||
|
msgstr "Conectando al servidor..."
|
||||||
|
|
||||||
|
msgid "Resolving address..."
|
||||||
|
msgstr "Resolviendo dirección..."
|
||||||
|
|
||||||
|
msgid "Creating client..."
|
||||||
|
msgstr "Creando cliente..."
|
||||||
|
|
||||||
|
msgid "Creating server...."
|
||||||
|
msgstr "Creando servidor..."
|
||||||
|
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Cargando..."
|
||||||
|
|
||||||
|
msgid "Local install"
|
||||||
|
msgstr "Instalación local"
|
||||||
|
|
||||||
|
msgid "Preload item visuals"
|
||||||
|
msgstr "Precarga elementos visuales"
|
||||||
|
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Contraseña"
|
||||||
|
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nombre"
|
||||||
|
|
||||||
|
msgid "Favorites:"
|
||||||
|
msgstr "Favoritos:"
|
||||||
|
|
||||||
|
msgid "<<-- Add mod"
|
||||||
|
msgstr "<<-- Añadir mod"
|
||||||
|
|
||||||
|
msgid "Remove selected mod"
|
||||||
|
msgstr "Eliminar el mod seleccionado"
|
||||||
|
|
||||||
|
msgid "Mods:"
|
||||||
|
msgstr "Mods:"
|
||||||
|
|
||||||
|
msgid "Games"
|
||||||
|
msgstr "Juegos"
|
||||||
|
|
||||||
|
msgid "Gamemgr: Unable to copy mod \"$1\" to game \"$2\""
|
||||||
|
msgstr "Gamemgr: Imposible copiar el mod \"$1\" al juego \"$2\""
|
||||||
|
|
||||||
|
msgid "Game Name"
|
||||||
|
msgstr "Nombre del juego"
|
||||||
|
|
||||||
|
msgid "Change Keys"
|
||||||
|
msgstr "Configurar teclas"
|
||||||
|
|
||||||
|
msgid "Name/Password"
|
||||||
|
msgstr "Nombre / contraseña:"
|
||||||
|
|
||||||
|
msgid "Node Highlighting"
|
||||||
|
msgstr "Resaltar nodos"
|
||||||
|
|
||||||
|
msgid "Texturing:"
|
||||||
|
msgstr "Texturizado:"
|
||||||
|
|
||||||
|
msgid "Rendering:"
|
||||||
|
msgstr "Renderizado:"
|
||||||
|
|
||||||
|
msgid "Rebuilding shaders..."
|
||||||
|
msgstr "Reconstruyendo sombreadores..."
|
||||||
|
|
||||||
|
msgid "Initializing nodes..."
|
||||||
|
msgstr "Inicializando nodos..."
|
||||||
|
|
||||||
|
msgid "Done!"
|
||||||
|
msgstr "¡Completado!"
|
||||||
|
|
|
@ -1,185 +1,215 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: minetest\n"
|
"Project-Id-Version: minetest\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2015-02-14 23:12+0900\n"
|
"POT-Creation-Date: 2013-11-23 17:37+0100\n"
|
||||||
"PO-Revision-Date: 2015-02-22 10:57+0900\n"
|
"PO-Revision-Date: 2014-12-28 15:48+0900\n"
|
||||||
"Last-Translator: Rui Takeda <mrrst0914@gmail.com>\n"
|
"Last-Translator: Rui Takeda <mrrst0914@gmail.com>\n"
|
||||||
"Language-Team: Japanese <minetest_jp@m.add.ac>\n"
|
"Language-Team: Japanese\n"
|
||||||
"Language: ja\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Poedit 1.6.5\n"
|
"X-Generator: Poedit 1.6.5\n"
|
||||||
|
"Language: ja_JP\n"
|
||||||
|
"X-Poedit-SourceCharset: UTF-8\n"
|
||||||
|
|
||||||
msgid "Ok"
|
msgid "Game Name"
|
||||||
msgstr "決定"
|
msgstr "ゲーム名"
|
||||||
|
|
||||||
msgid "World:"
|
msgid "Create"
|
||||||
msgstr "ワールド:"
|
msgstr "作成"
|
||||||
|
|
||||||
msgid "Hide Game"
|
|
||||||
msgstr "ゲームを隠す"
|
|
||||||
|
|
||||||
msgid "Hide mp content"
|
|
||||||
msgstr "Modパックの簡略化"
|
|
||||||
|
|
||||||
msgid "Mod:"
|
|
||||||
msgstr "Mod名:"
|
|
||||||
|
|
||||||
msgid "Depends:"
|
|
||||||
msgstr "依存Mod:"
|
|
||||||
|
|
||||||
msgid "Save"
|
|
||||||
msgstr "保存"
|
|
||||||
|
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "キャンセル"
|
msgstr "キャンセル"
|
||||||
|
|
||||||
msgid "Enable MP"
|
msgid "Gamemgr: Unable to copy mod \"$1\" to game \"$2\""
|
||||||
msgstr "有効化"
|
msgstr "Gamemgr: \"$1\"のModを \"$2\" にコピーできません"
|
||||||
|
|
||||||
msgid "Disable MP"
|
msgid "Games"
|
||||||
msgstr "無効化"
|
msgstr "ゲーム"
|
||||||
|
|
||||||
msgid "enabled"
|
msgid "Mods:"
|
||||||
msgstr "有効化"
|
msgstr "Mod:"
|
||||||
|
|
||||||
msgid "Enable all"
|
msgid "edit game"
|
||||||
msgstr "すべて有効化"
|
msgstr "ゲーム編集"
|
||||||
|
|
||||||
|
msgid "new game"
|
||||||
|
msgstr "新規ゲーム"
|
||||||
|
|
||||||
|
msgid "Remove selected mod"
|
||||||
|
msgstr "選択したModを削除"
|
||||||
|
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "決定"
|
||||||
|
|
||||||
msgid "World name"
|
msgid "World name"
|
||||||
msgstr "ワールド名"
|
msgstr "ワールド名"
|
||||||
|
|
||||||
msgid "Seed"
|
msgid "Seed"
|
||||||
msgstr "Seed値"
|
msgstr "シード値"
|
||||||
|
|
||||||
msgid "Mapgen"
|
msgid "Mapgen"
|
||||||
msgstr "ワールドタイプ"
|
msgstr "マップ生成"
|
||||||
|
|
||||||
msgid "Game"
|
msgid "Game"
|
||||||
msgstr "ゲーム"
|
msgstr "ゲーム"
|
||||||
|
|
||||||
msgid "Create"
|
msgid "Delete World \"$1\"?"
|
||||||
msgstr "作成"
|
msgstr "\"$1\"のワールドを削除しますか?"
|
||||||
|
|
||||||
msgid "You have no subgames installed."
|
|
||||||
msgstr "ゲームがインストールされていません。"
|
|
||||||
|
|
||||||
msgid "Download one from minetest.net"
|
|
||||||
msgstr "minetest.netから再ダウンロードしてください。"
|
|
||||||
|
|
||||||
msgid "Warning: The minimal development test is meant for developers."
|
|
||||||
msgstr "警告:Minimal development testは開発者のためのゲームです。"
|
|
||||||
|
|
||||||
msgid "Download a subgame, such as minetest_game, from minetest.net"
|
|
||||||
msgstr "minetest.netからminetest_gameのゲームをダウンロードしてください。"
|
|
||||||
|
|
||||||
msgid "A world named \"$1\" already exists"
|
|
||||||
msgstr "ワールド名\"$1\"はすでに使用されています。"
|
|
||||||
|
|
||||||
msgid "No worldname given or no game selected"
|
|
||||||
msgstr "ワールド名が入力されていないか、ゲームが選択されていません。"
|
|
||||||
|
|
||||||
msgid "Are you sure you want to delete \"$1\"?"
|
|
||||||
msgstr "本当に\"$1\"を削除してよろしいですか?"
|
|
||||||
|
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr "はい"
|
msgstr "はい"
|
||||||
|
|
||||||
msgid "No of course not!"
|
|
||||||
msgstr "いいえ"
|
|
||||||
|
|
||||||
msgid "Modmgr: failed to delete \"$1\""
|
|
||||||
msgstr "Modマネージャー:\"$1\"の削除に失敗しました。"
|
|
||||||
|
|
||||||
msgid "Modmgr: invalid modpath \"$1\""
|
|
||||||
msgstr "Modマネージャー:Mod\"$1\"の場所が不明です。"
|
|
||||||
|
|
||||||
msgid "Delete World \"$1\"?"
|
|
||||||
msgstr "ワールド\"$1\"を削除してよろしいですか?"
|
|
||||||
|
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "いいえ"
|
msgstr "いいえ"
|
||||||
|
|
||||||
msgid "Rename Modpack:"
|
msgid "A world named \"$1\" already exists"
|
||||||
msgstr "名前を変更"
|
msgstr "\"$1\"という名前のワールドを作成できません。同名のワールドが存在しています"
|
||||||
|
|
||||||
msgid "Accept"
|
msgid "No worldname given or no game selected"
|
||||||
msgstr "決定"
|
msgstr "ワールド名が入力されていないか、ゲームが選択されていません"
|
||||||
|
|
||||||
msgid "Install Mod: file: \"$1\""
|
msgid "To enable shaders the OpenGL driver needs to be used."
|
||||||
msgstr "Modインストール:ファイル\"$1\"からModをインストールします。"
|
msgstr "シェーダーを有効にするには、OpenGLのドライバが必要です"
|
||||||
|
|
||||||
msgid ""
|
msgid "Address/Port"
|
||||||
"\n"
|
msgstr "アドレス/ポート"
|
||||||
"Install Mod: unsupported filetype \"$1\" or broken archive"
|
|
||||||
msgstr ""
|
|
||||||
"\n"
|
|
||||||
"Modインストール:ファイル\"$1\"は非対応の形式か、壊れています。"
|
|
||||||
|
|
||||||
msgid "Failed to install $1 to $2"
|
msgid "Name/Password"
|
||||||
msgstr "$2へ$1をインストールできませんでした。"
|
msgstr "名前/パスワード"
|
||||||
|
|
||||||
msgid "Install Mod: unable to find suitable foldername for modpack $1"
|
msgid "Public Serverlist"
|
||||||
msgstr ""
|
msgstr "公開されているサーバーリスト"
|
||||||
"Modインストール:Modパック$1に適したフォルダ名を見つけることができませんでし"
|
|
||||||
"た。"
|
|
||||||
|
|
||||||
msgid "Install Mod: unable to find real modname for: $1"
|
msgid "Delete"
|
||||||
msgstr "Modインストール:$1の本来のMod名が不明です。"
|
msgstr "削除"
|
||||||
|
|
||||||
msgid "Unsorted"
|
msgid "Connect"
|
||||||
msgstr "未分類"
|
msgstr "接続"
|
||||||
|
|
||||||
msgid "Search"
|
msgid "New"
|
||||||
msgstr "検索"
|
msgstr "作成"
|
||||||
|
|
||||||
msgid "Downloading $1, please wait..."
|
msgid "Configure"
|
||||||
msgstr "$1をダウンロードしています。しばらくお待ちください..."
|
msgstr "設定"
|
||||||
|
|
||||||
msgid "Successfully installed:"
|
msgid "Start Game"
|
||||||
msgstr "インストールが完了しました。:"
|
msgstr "ゲームスタート"
|
||||||
|
|
||||||
msgid "Shortname:"
|
msgid "Select World:"
|
||||||
msgstr "省略名"
|
msgstr "ワールド選択:"
|
||||||
|
|
||||||
msgid "Rating"
|
msgid "Creative Mode"
|
||||||
msgstr "評価"
|
msgstr "クリエイティブモード"
|
||||||
|
|
||||||
msgid "re-Install"
|
msgid "Enable Damage"
|
||||||
msgstr "再インストール"
|
msgstr "ダメージ有効"
|
||||||
|
|
||||||
msgid "Install"
|
msgid "Public"
|
||||||
msgstr "インストール"
|
msgstr "公開する"
|
||||||
|
|
||||||
msgid "Close store"
|
msgid "Name"
|
||||||
msgstr "閉じる"
|
msgstr "名前"
|
||||||
|
|
||||||
msgid "Page $1 of $2"
|
msgid "Password"
|
||||||
msgstr "ページ $1/$2"
|
msgstr "パスワード"
|
||||||
|
|
||||||
msgid "Credits"
|
msgid "Server Port"
|
||||||
msgstr "クレジット"
|
msgstr "ポート"
|
||||||
|
|
||||||
|
msgid "Fancy Trees"
|
||||||
|
msgstr "きれいな木"
|
||||||
|
|
||||||
|
msgid "Smooth Lighting"
|
||||||
|
msgstr "自然な光"
|
||||||
|
|
||||||
|
msgid "3D Clouds"
|
||||||
|
msgstr "立体な雲"
|
||||||
|
|
||||||
|
msgid "Opaque Water"
|
||||||
|
msgstr "不透明な水面"
|
||||||
|
|
||||||
|
msgid "Mip-Mapping"
|
||||||
|
msgstr "ミップマップ"
|
||||||
|
|
||||||
|
msgid "Anisotropic Filtering"
|
||||||
|
msgstr "異方性フィルタリング"
|
||||||
|
|
||||||
|
msgid "Bi-Linear Filtering"
|
||||||
|
msgstr "バイリニアフィルタリング"
|
||||||
|
|
||||||
|
msgid "Tri-Linear Filtering"
|
||||||
|
msgstr "トリリニアフィルタリング"
|
||||||
|
|
||||||
|
msgid "Shaders"
|
||||||
|
msgstr "シェーダー"
|
||||||
|
|
||||||
|
msgid "Connected Glass"
|
||||||
|
msgstr "ガラスを繋げる"
|
||||||
|
|
||||||
|
msgid "Enable Particles"
|
||||||
|
msgstr "破片の有効化"
|
||||||
|
|
||||||
|
msgid "Finite Liquid"
|
||||||
|
msgstr "液体の制限"
|
||||||
|
|
||||||
|
msgid "Change keys"
|
||||||
|
msgstr "キー割当て変更"
|
||||||
|
|
||||||
|
msgid "Play"
|
||||||
|
msgstr "ゲームスタート"
|
||||||
|
|
||||||
|
msgid "Select texture pack:"
|
||||||
|
msgstr "テクスチャパックを選択:"
|
||||||
|
|
||||||
|
msgid "No information available"
|
||||||
|
msgstr "情報がありません"
|
||||||
|
|
||||||
msgid "Core Developers"
|
msgid "Core Developers"
|
||||||
msgstr "開発者"
|
msgstr "開発者"
|
||||||
|
|
||||||
msgid "Active Contributors"
|
msgid "Active Contributors"
|
||||||
msgstr "開発協力者"
|
msgstr "貢献者"
|
||||||
|
|
||||||
msgid "Previous Contributors"
|
msgid "Previous Contributors"
|
||||||
msgstr "以前の開発協力者"
|
msgstr "以前の貢献者"
|
||||||
|
|
||||||
|
msgid "Singleplayer"
|
||||||
|
msgstr "シングルプレイ"
|
||||||
|
|
||||||
|
msgid "Client"
|
||||||
|
msgstr "クライアント"
|
||||||
|
|
||||||
|
msgid "Server"
|
||||||
|
msgstr "マルチプレイ"
|
||||||
|
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "設定"
|
||||||
|
|
||||||
|
msgid "Texturepacks"
|
||||||
|
msgstr "テクスチャパック"
|
||||||
|
|
||||||
|
msgid "Mods"
|
||||||
|
msgstr "Mod"
|
||||||
|
|
||||||
|
msgid "Credits"
|
||||||
|
msgstr "クレジット"
|
||||||
|
|
||||||
msgid "Installed Mods:"
|
msgid "Installed Mods:"
|
||||||
msgstr "インストール済みのMod:"
|
msgstr "インストール済みのMod:"
|
||||||
|
|
||||||
msgid "Online mod repository"
|
msgid "Online mod repository"
|
||||||
msgstr "オンラインでModを検索"
|
msgstr "オンラインで検索"
|
||||||
|
|
||||||
msgid "No mod description available"
|
msgid "No mod description available"
|
||||||
msgstr "Modの説明がありません。"
|
msgstr "Modの説明がありません"
|
||||||
|
|
||||||
msgid "Mod information:"
|
msgid "Mod information:"
|
||||||
msgstr "Modの情報:"
|
msgstr "Modの情報:"
|
||||||
|
@ -193,376 +223,123 @@ msgstr "選択したModパックを削除"
|
||||||
msgid "Uninstall selected mod"
|
msgid "Uninstall selected mod"
|
||||||
msgstr "選択したModを削除"
|
msgstr "選択したModを削除"
|
||||||
|
|
||||||
msgid "Select Mod File:"
|
msgid "Rename Modpack:"
|
||||||
msgstr "Modファイルを選択"
|
msgstr "Modパックの名前を変更"
|
||||||
|
|
||||||
msgid "Mods"
|
msgid "Accept"
|
||||||
msgstr "Mod"
|
msgstr "了承"
|
||||||
|
|
||||||
msgid "Address / Port :"
|
msgid "World:"
|
||||||
msgstr "アドレスとポート:"
|
msgstr "ワールド:"
|
||||||
|
|
||||||
msgid "Name / Password :"
|
msgid "Hide Game"
|
||||||
msgstr "名前とパスワード:"
|
msgstr "内部Mod"
|
||||||
|
|
||||||
msgid "Public Serverlist"
|
msgid "Hide mp content"
|
||||||
msgstr "公開済みのサーバーの一覧"
|
msgstr "Modパックの簡略化"
|
||||||
|
|
||||||
msgid "Delete"
|
msgid "Mod:"
|
||||||
msgstr "削除"
|
msgstr "Mod名:"
|
||||||
|
|
||||||
msgid "Connect"
|
msgid "Depends:"
|
||||||
msgstr "接続"
|
msgstr "依存Mod:"
|
||||||
|
|
||||||
msgid "Creative mode"
|
msgid "Save"
|
||||||
msgstr "クリエイティブモード"
|
msgstr "保存"
|
||||||
|
|
||||||
msgid "Damage enabled"
|
msgid "Enable MP"
|
||||||
msgstr "HPあり"
|
msgstr "有効化"
|
||||||
|
|
||||||
msgid "PvP enabled"
|
msgid "Disable MP"
|
||||||
msgstr "PvPあり"
|
msgstr "無効化"
|
||||||
|
|
||||||
msgid "Client"
|
msgid "enabled"
|
||||||
msgstr "クライアント"
|
msgstr "有効化"
|
||||||
|
|
||||||
msgid "New"
|
msgid "Enable all"
|
||||||
msgstr "作成"
|
msgstr "全て有効化"
|
||||||
|
|
||||||
msgid "Configure"
|
msgid "Modmgr: failed to delete \"$1\""
|
||||||
msgstr "設定"
|
msgstr "Modmgr: \"$1\"の削除に失敗しました"
|
||||||
|
|
||||||
msgid "Start Game"
|
msgid "Modmgr: invalid modpath \"$1\""
|
||||||
msgstr "ゲームスタート"
|
msgstr "Modmgr: \"$1\"は無効なModパスです"
|
||||||
|
|
||||||
msgid "Select World:"
|
msgid "Are you sure you want to delete \"$1\"?"
|
||||||
msgstr "ワールドを選択:"
|
msgstr "\"$1\"を削除してよろしいですか?"
|
||||||
|
|
||||||
msgid "Creative Mode"
|
msgid "No of course not!"
|
||||||
msgstr "クリエイティブモード"
|
msgstr "違います!"
|
||||||
|
|
||||||
msgid "Enable Damage"
|
msgid "Page $1 of $2"
|
||||||
msgstr "ダメージあり"
|
msgstr "ページ $1/$2"
|
||||||
|
|
||||||
msgid "Public"
|
msgid "Rating"
|
||||||
msgstr "サーバーを公開する"
|
msgstr "評価"
|
||||||
|
|
||||||
msgid "Name/Password"
|
msgid "re-Install"
|
||||||
msgstr "名前とパスワード"
|
msgstr "再インストール"
|
||||||
|
|
||||||
msgid "Bind Address"
|
msgid "Install"
|
||||||
msgstr "バインドアドレス"
|
msgstr "インストール"
|
||||||
|
|
||||||
msgid "Port"
|
|
||||||
msgstr "ポート"
|
|
||||||
|
|
||||||
msgid "Server Port"
|
|
||||||
msgstr "サーバーのポート"
|
|
||||||
|
|
||||||
msgid "Server"
|
|
||||||
msgstr "サーバー"
|
|
||||||
|
|
||||||
msgid "No Filter"
|
|
||||||
msgstr "フィルタ無し"
|
|
||||||
|
|
||||||
msgid "Bilinear Filter"
|
|
||||||
msgstr "バイリニアフィルタ"
|
|
||||||
|
|
||||||
msgid "Trilinear Filter"
|
|
||||||
msgstr "トリリニアフィルタ"
|
|
||||||
|
|
||||||
msgid "No Mipmap"
|
|
||||||
msgstr "ミップマップ無し"
|
|
||||||
|
|
||||||
msgid "Mipmap"
|
|
||||||
msgstr "ミップマップ"
|
|
||||||
|
|
||||||
msgid "Mipmap + Aniso. Filter"
|
|
||||||
msgstr "異方性フィルタ"
|
|
||||||
|
|
||||||
msgid "Are you sure to reset your singleplayer world?"
|
|
||||||
msgstr "シングルプレイヤーのワールドをリセットしてよろしいですか?"
|
|
||||||
|
|
||||||
msgid "No!!!"
|
|
||||||
msgstr "いいえ"
|
|
||||||
|
|
||||||
msgid "Smooth Lighting"
|
|
||||||
msgstr "滑らかな光"
|
|
||||||
|
|
||||||
msgid "Enable Particles"
|
|
||||||
msgstr "パーティクル有効化"
|
|
||||||
|
|
||||||
msgid "3D Clouds"
|
|
||||||
msgstr "立体の雲"
|
|
||||||
|
|
||||||
msgid "Fancy Trees"
|
|
||||||
msgstr "綺麗な木"
|
|
||||||
|
|
||||||
msgid "Opaque Water"
|
|
||||||
msgstr "不透明な水"
|
|
||||||
|
|
||||||
msgid "Connected Glass"
|
|
||||||
msgstr "ガラスをつなげる"
|
|
||||||
|
|
||||||
msgid "Node Highlighting"
|
|
||||||
msgstr "ノードの強調"
|
|
||||||
|
|
||||||
msgid "Texturing:"
|
|
||||||
msgstr "テクスチャリング:"
|
|
||||||
|
|
||||||
msgid "Rendering:"
|
|
||||||
msgstr "レンダリング:"
|
|
||||||
|
|
||||||
msgid "Restart minetest for driver change to take effect"
|
|
||||||
msgstr "ドライバーを変更するためMinetesを再起動します"
|
|
||||||
|
|
||||||
msgid "Shaders"
|
|
||||||
msgstr "シェーダー"
|
|
||||||
|
|
||||||
msgid "Change keys"
|
|
||||||
msgstr "操作変更"
|
|
||||||
|
|
||||||
msgid "Reset singleplayer world"
|
|
||||||
msgstr "シングルプレイヤーのワールドをリセット"
|
|
||||||
|
|
||||||
msgid "GUI scale factor"
|
|
||||||
msgstr "メニューの大きさ"
|
|
||||||
|
|
||||||
msgid "Scaling factor applied to menu elements: "
|
|
||||||
msgstr "メニューの大きさとして設定する数値:"
|
|
||||||
|
|
||||||
msgid "Touch free target"
|
|
||||||
msgstr "タッチ位置を自由にする"
|
|
||||||
|
|
||||||
msgid "Touchthreshold (px)"
|
|
||||||
msgstr "タッチのしきい値(ピクセル単位)"
|
|
||||||
|
|
||||||
msgid "Bumpmapping"
|
|
||||||
msgstr "バンプマッピング"
|
|
||||||
|
|
||||||
msgid "Generate Normalmaps"
|
|
||||||
msgstr "ノーマルマップの生成"
|
|
||||||
|
|
||||||
msgid "Parallax Occlusion"
|
|
||||||
msgstr "視差遮蔽マッピング"
|
|
||||||
|
|
||||||
msgid "Waving Water"
|
|
||||||
msgstr "揺れる水"
|
|
||||||
|
|
||||||
msgid "Waving Leaves"
|
|
||||||
msgstr "揺れる葉"
|
|
||||||
|
|
||||||
msgid "Waving Plants"
|
|
||||||
msgstr "揺れる草花"
|
|
||||||
|
|
||||||
msgid "To enable shaders the OpenGL driver needs to be used."
|
|
||||||
msgstr "シェーダーを有効にするにはOpenGLを使用する必要があります。"
|
|
||||||
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr "設定"
|
|
||||||
|
|
||||||
msgid "Fly mode"
|
|
||||||
msgstr "飛行モード"
|
|
||||||
|
|
||||||
msgid "Start Singleplayer"
|
|
||||||
msgstr "ゲームスタート"
|
|
||||||
|
|
||||||
msgid "Config mods"
|
|
||||||
msgstr "Mod設定"
|
|
||||||
|
|
||||||
msgid "Main"
|
|
||||||
msgstr "メイン"
|
|
||||||
|
|
||||||
msgid "Play"
|
|
||||||
msgstr "ゲームスタート"
|
|
||||||
|
|
||||||
msgid "Singleplayer"
|
|
||||||
msgstr "シングルプレイヤー"
|
|
||||||
|
|
||||||
msgid "Select texture pack:"
|
|
||||||
msgstr "テクスチャパックを選択:"
|
|
||||||
|
|
||||||
msgid "No information available"
|
|
||||||
msgstr "情報がありません。"
|
|
||||||
|
|
||||||
msgid "Texturepacks"
|
|
||||||
msgstr "テクスチャパック"
|
|
||||||
|
|
||||||
msgid "Loading textures..."
|
|
||||||
msgstr "テクスチャ読み込み中..."
|
|
||||||
|
|
||||||
msgid "Rebuilding shaders..."
|
|
||||||
msgstr "シェーダー構築中..."
|
|
||||||
|
|
||||||
msgid "Initializing nodes..."
|
|
||||||
msgstr "ノードの設定中..."
|
|
||||||
|
|
||||||
msgid "Item textures..."
|
msgid "Item textures..."
|
||||||
msgstr "アイテムのテクスチャを設定中..."
|
msgstr "アイテムのテクスチャ設定中..."
|
||||||
|
|
||||||
msgid "Done!"
|
|
||||||
msgstr "完了!"
|
|
||||||
|
|
||||||
msgid "Main Menu"
|
|
||||||
msgstr "メインメニュー"
|
|
||||||
|
|
||||||
msgid "Player name too long."
|
|
||||||
msgstr "名前が長過ぎます。"
|
|
||||||
|
|
||||||
msgid "Connection error (timed out?)"
|
|
||||||
msgstr "接続失敗(またはタイムアウト)"
|
|
||||||
|
|
||||||
msgid "No world selected and no address provided. Nothing to do."
|
|
||||||
msgstr "ワールドが選択されていないアドレスです。続行できません。"
|
|
||||||
|
|
||||||
msgid "Provided world path doesn't exist: "
|
|
||||||
msgstr "ワールドが存在しません:"
|
|
||||||
|
|
||||||
msgid "Could not find or load game \""
|
|
||||||
msgstr "ゲーム\"の読み込みができません。"
|
|
||||||
|
|
||||||
msgid "Invalid gamespec."
|
|
||||||
msgstr "無効なgamespecです。"
|
|
||||||
|
|
||||||
msgid "needs_fallback_font"
|
|
||||||
msgstr "yes"
|
|
||||||
|
|
||||||
msgid "Proceed"
|
|
||||||
msgstr "決定"
|
|
||||||
|
|
||||||
msgid "You died."
|
|
||||||
msgstr "You died."
|
|
||||||
|
|
||||||
msgid "Respawn"
|
|
||||||
msgstr "Respawn"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Default Controls:\n"
|
|
||||||
"No menu visible:\n"
|
|
||||||
"- single tap: button activate\n"
|
|
||||||
"- double tap: place/use\n"
|
|
||||||
"- slide finger: look around\n"
|
|
||||||
"Menu/Inventory visible:\n"
|
|
||||||
"- double tap (outside):\n"
|
|
||||||
" -->close\n"
|
|
||||||
"- touch stack, touch slot:\n"
|
|
||||||
" --> move stack\n"
|
|
||||||
"- touch&drag, tap 2nd finger\n"
|
|
||||||
" --> place single item to slot\n"
|
|
||||||
msgstr ""
|
|
||||||
"基本操作:\n"
|
|
||||||
"タッチによる操作\n"
|
|
||||||
"- シングルタップ:ブロックの破壊\n"
|
|
||||||
"- ダブルタップ:設置やアイテムの使用\n"
|
|
||||||
"- 指でスライド:見回す\n"
|
|
||||||
"メニュー(インベントリ)の操作\n"
|
|
||||||
"- ダブルタップ:\n"
|
|
||||||
"-- 閉じる\n"
|
|
||||||
"- アイテムスロットをタッチ:\n"
|
|
||||||
"-- アイテムの移動\n"
|
|
||||||
"- タッチしてドラッグ:\n"
|
|
||||||
"-- アイテムを置く\n"
|
|
||||||
|
|
||||||
msgid ""
|
|
||||||
"Default Controls:\n"
|
|
||||||
"- WASD: move\n"
|
|
||||||
"- Space: jump/climb\n"
|
|
||||||
"- Shift: sneak/go down\n"
|
|
||||||
"- Q: drop item\n"
|
|
||||||
"- I: inventory\n"
|
|
||||||
"- Mouse: turn/look\n"
|
|
||||||
"- Mouse left: dig/punch\n"
|
|
||||||
"- Mouse right: place/use\n"
|
|
||||||
"- Mouse wheel: select item\n"
|
|
||||||
"- T: chat\n"
|
|
||||||
msgstr ""
|
|
||||||
"基本操作:\n"
|
|
||||||
"- WASD:移動\n"
|
|
||||||
"- スペース:ジャンプ、登る\n"
|
|
||||||
"- Shift:スニーク、降りる\n"
|
|
||||||
"- Q:アイテムを落とす\n"
|
|
||||||
"- I:インベントリ\n"
|
|
||||||
"- マウス移動:見回す\n"
|
|
||||||
"- 左クリック:ブロック破壊\n"
|
|
||||||
"- 右クリック:設置や使用\n"
|
|
||||||
"- ホイール:アイテム選択\n"
|
|
||||||
"- T:チャット画面\n"
|
|
||||||
|
|
||||||
msgid "Continue"
|
|
||||||
msgstr "再開"
|
|
||||||
|
|
||||||
msgid "Change Password"
|
|
||||||
msgstr "パスワード変更"
|
|
||||||
|
|
||||||
msgid "Sound Volume"
|
|
||||||
msgstr "音量"
|
|
||||||
|
|
||||||
msgid "Change Keys"
|
|
||||||
msgstr "操作変更"
|
|
||||||
|
|
||||||
msgid "Exit to Menu"
|
|
||||||
msgstr "タイトル"
|
|
||||||
|
|
||||||
msgid "Exit to OS"
|
|
||||||
msgstr "終了"
|
|
||||||
|
|
||||||
msgid "Shutting down..."
|
|
||||||
msgstr "終了中..."
|
|
||||||
|
|
||||||
msgid "Loading..."
|
msgid "Loading..."
|
||||||
msgstr "読み込み中..."
|
msgstr "ロード中..."
|
||||||
|
|
||||||
msgid "Creating server..."
|
msgid "Creating server..."
|
||||||
msgstr "サーバー作成中..."
|
msgstr "サーバー構築中..."
|
||||||
|
|
||||||
msgid "Creating client..."
|
msgid "Creating client..."
|
||||||
msgstr "クライアント作成中..."
|
msgstr "クライアント作成中..."
|
||||||
|
|
||||||
msgid "Resolving address..."
|
msgid "Resolving address..."
|
||||||
msgstr "アドレス解決中..."
|
msgstr "アドレス解決中..."
|
||||||
|
|
||||||
msgid "Connecting to server..."
|
msgid "Connecting to server..."
|
||||||
msgstr "サーバー接続中..."
|
msgstr "サーバー接続中..."
|
||||||
|
|
||||||
msgid "Item definitions..."
|
msgid "Item definitions..."
|
||||||
msgstr "アイテム定義中..."
|
msgstr "アイテム定義中..."
|
||||||
|
|
||||||
msgid "Node definitions..."
|
msgid "Node definitions..."
|
||||||
msgstr "ノード定義中..."
|
msgstr "ノード定義中..."
|
||||||
|
|
||||||
msgid "Media..."
|
msgid "Media..."
|
||||||
msgstr "..."
|
msgstr "..."
|
||||||
|
|
||||||
msgid " KB/s"
|
msgid "Shutting down..."
|
||||||
msgstr " KB/秒"
|
msgstr "終了中..."
|
||||||
|
|
||||||
msgid " MB/s"
|
|
||||||
msgstr " MB/秒"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
"Check debug.txt for details."
|
"Check debug.txt for details."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"詳細はdebug.txtをご覧ください。"
|
"詳細はdebug.txtを御覧ください。"
|
||||||
|
|
||||||
msgid "Enter "
|
msgid "You died."
|
||||||
msgstr "Enter"
|
msgstr "You died!"
|
||||||
|
|
||||||
msgid "ok"
|
msgid "Respawn"
|
||||||
|
msgstr "Respawn"
|
||||||
|
|
||||||
|
msgid "Proceed"
|
||||||
msgstr "決定"
|
msgstr "決定"
|
||||||
|
|
||||||
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
||||||
msgstr "操作の設定を変更します。"
|
msgstr "キーバインド"
|
||||||
|
|
||||||
msgid "\"Use\" = climb down"
|
msgid "\"Use\" = climb down"
|
||||||
msgstr "「使用」で降りる"
|
msgstr "「使う」キーで降りる"
|
||||||
|
|
||||||
msgid "Double tap \"jump\" to toggle fly"
|
msgid "Double tap \"jump\" to toggle fly"
|
||||||
msgstr "「ジャンプ」二回押しで飛行モード"
|
msgstr "ジャンプの二回押しで飛行"
|
||||||
|
|
||||||
msgid "Key already in use"
|
msgid "Key already in use"
|
||||||
msgstr "すでに使われているキーです。"
|
msgstr "既に使われているキーです"
|
||||||
|
|
||||||
msgid "press key"
|
msgid "press key"
|
||||||
msgstr "キー入力待ち"
|
msgstr "キー入力待ち"
|
||||||
|
@ -574,19 +351,19 @@ msgid "Backward"
|
||||||
msgstr "後退"
|
msgstr "後退"
|
||||||
|
|
||||||
msgid "Left"
|
msgid "Left"
|
||||||
msgstr "左に進む"
|
msgstr "左へ進む"
|
||||||
|
|
||||||
msgid "Right"
|
msgid "Right"
|
||||||
msgstr "右に進む"
|
msgstr "右へ進む"
|
||||||
|
|
||||||
msgid "Use"
|
msgid "Use"
|
||||||
msgstr "使用"
|
msgstr "使う"
|
||||||
|
|
||||||
msgid "Jump"
|
msgid "Jump"
|
||||||
msgstr "ジャンプ"
|
msgstr "ジャンプ"
|
||||||
|
|
||||||
msgid "Sneak"
|
msgid "Sneak"
|
||||||
msgstr "スニーク"
|
msgstr "こっそり進む"
|
||||||
|
|
||||||
msgid "Drop"
|
msgid "Drop"
|
||||||
msgstr "落とす"
|
msgstr "落とす"
|
||||||
|
@ -604,16 +381,16 @@ msgid "Console"
|
||||||
msgstr "コンソール"
|
msgstr "コンソール"
|
||||||
|
|
||||||
msgid "Toggle fly"
|
msgid "Toggle fly"
|
||||||
msgstr "飛行モード"
|
msgstr "飛行"
|
||||||
|
|
||||||
msgid "Toggle fast"
|
msgid "Toggle fast"
|
||||||
msgstr "高速移動モード"
|
msgstr "高速移動"
|
||||||
|
|
||||||
msgid "Toggle noclip"
|
msgid "Toggle noclip"
|
||||||
msgstr "すり抜けモード"
|
msgstr "すり抜け"
|
||||||
|
|
||||||
msgid "Range select"
|
msgid "Range select"
|
||||||
msgstr "視野範囲変更"
|
msgstr "視野切り替え"
|
||||||
|
|
||||||
msgid "Print stacks"
|
msgid "Print stacks"
|
||||||
msgstr "スタックの表示"
|
msgstr "スタックの表示"
|
||||||
|
@ -631,13 +408,53 @@ msgid "Change"
|
||||||
msgstr "変更"
|
msgstr "変更"
|
||||||
|
|
||||||
msgid "Passwords do not match!"
|
msgid "Passwords do not match!"
|
||||||
msgstr "パスワードが一致しません!"
|
msgstr "パスワードが一致しません!"
|
||||||
|
|
||||||
|
msgid "Continue"
|
||||||
|
msgstr "続ける"
|
||||||
|
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr "パスワード変更"
|
||||||
|
|
||||||
|
msgid "Sound Volume"
|
||||||
|
msgstr "音量"
|
||||||
|
|
||||||
|
msgid "Exit to Menu"
|
||||||
|
msgstr "タイトル"
|
||||||
|
|
||||||
|
msgid "Exit to OS"
|
||||||
|
msgstr "終了"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Default Controls:\n"
|
||||||
|
"- WASD: move\n"
|
||||||
|
"- Space: jump/climb\n"
|
||||||
|
"- Shift: sneak/go down\n"
|
||||||
|
"- Q: drop item\n"
|
||||||
|
"- I: inventory\n"
|
||||||
|
"- Mouse: turn/look\n"
|
||||||
|
"- Mouse left: dig/punch\n"
|
||||||
|
"- Mouse right: place/use\n"
|
||||||
|
"- Mouse wheel: select item\n"
|
||||||
|
"- T: chat\n"
|
||||||
|
msgstr ""
|
||||||
|
"基本操作:\n"
|
||||||
|
"WASD:移動\n"
|
||||||
|
"スペース:ジャンプ/登る\n"
|
||||||
|
"シフト:忍び歩き/降りる\n"
|
||||||
|
"Q:アイテムを落とす\n"
|
||||||
|
"I:インベントリ\n"
|
||||||
|
"マウス:見回す\n"
|
||||||
|
"左クリック:掘る/パンチ\n"
|
||||||
|
"右クリック:使う\n"
|
||||||
|
"マウスホイール:アイテム選択\n"
|
||||||
|
"T:チャット\n"
|
||||||
|
|
||||||
msgid "Sound Volume: "
|
msgid "Sound Volume: "
|
||||||
msgstr "音量:"
|
msgstr "音量"
|
||||||
|
|
||||||
msgid "Exit"
|
msgid "Exit"
|
||||||
msgstr "閉じる"
|
msgstr "戻る"
|
||||||
|
|
||||||
msgid "Left Button"
|
msgid "Left Button"
|
||||||
msgstr "左ボタン"
|
msgstr "左ボタン"
|
||||||
|
@ -854,3 +671,56 @@ msgstr "PA1"
|
||||||
|
|
||||||
msgid "Zoom"
|
msgid "Zoom"
|
||||||
msgstr "ズーム"
|
msgstr "ズーム"
|
||||||
|
|
||||||
|
msgid "needs_fallback_font"
|
||||||
|
msgstr "yes"
|
||||||
|
|
||||||
|
msgid "Main Menu"
|
||||||
|
msgstr "メインメニュー"
|
||||||
|
|
||||||
|
msgid "No world selected and no address provided. Nothing to do."
|
||||||
|
msgstr ""
|
||||||
|
"ワールドが選択できていないか、アドレスが入力されていません。そのため実行されませ"
|
||||||
|
"ん。"
|
||||||
|
|
||||||
|
msgid "Could not find or load game \""
|
||||||
|
msgstr "読み込みか検索に失敗: \""
|
||||||
|
|
||||||
|
msgid "Invalid gamespec."
|
||||||
|
msgstr "無効なgamespecです"
|
||||||
|
|
||||||
|
msgid "Connection error (timed out?)"
|
||||||
|
msgstr "接続エラー(タイムアウト)"
|
||||||
|
|
||||||
|
msgid "Bumpmapping"
|
||||||
|
msgstr "バンプマッピング"
|
||||||
|
|
||||||
|
msgid "Generate Normalmaps"
|
||||||
|
msgstr "法線マッピング"
|
||||||
|
|
||||||
|
msgid "Parallax Occlusion"
|
||||||
|
msgstr "視差オクルージョンマッピング"
|
||||||
|
|
||||||
|
msgid "Waving Water"
|
||||||
|
msgstr "揺れる水"
|
||||||
|
|
||||||
|
msgid "Waving Leaves"
|
||||||
|
msgstr "揺れる葉"
|
||||||
|
|
||||||
|
msgid "Waving Plants"
|
||||||
|
msgstr "揺れる草花"
|
||||||
|
|
||||||
|
msgid "GUI scale factor"
|
||||||
|
msgstr "メニューの大きさ"
|
||||||
|
|
||||||
|
msgid "Unsorted"
|
||||||
|
msgstr "未分類"
|
||||||
|
|
||||||
|
msgid "Search"
|
||||||
|
msgstr "検索"
|
||||||
|
|
||||||
|
msgid "Close store"
|
||||||
|
msgstr "閉じる"
|
||||||
|
|
||||||
|
msgid "Change Keys"
|
||||||
|
msgstr "操作変更"
|
||||||
|
|
1248
po/tr/minetest.po
1248
po/tr/minetest.po
File diff suppressed because it is too large
Load Diff
|
@ -352,19 +352,16 @@ add_custom_target(GenerateVersion
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
add_subdirectory(jthread)
|
add_subdirectory(jthread)
|
||||||
add_subdirectory(network)
|
|
||||||
add_subdirectory(script)
|
add_subdirectory(script)
|
||||||
add_subdirectory(util)
|
add_subdirectory(util)
|
||||||
|
|
||||||
set (unittests_SRCS
|
|
||||||
test.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(common_SRCS
|
set(common_SRCS
|
||||||
ban.cpp
|
ban.cpp
|
||||||
|
base64.cpp
|
||||||
cavegen.cpp
|
cavegen.cpp
|
||||||
clientiface.cpp
|
clientiface.cpp
|
||||||
collision.cpp
|
collision.cpp
|
||||||
|
connection.cpp
|
||||||
content_abm.cpp
|
content_abm.cpp
|
||||||
content_mapnode.cpp
|
content_mapnode.cpp
|
||||||
content_nodemeta.cpp
|
content_nodemeta.cpp
|
||||||
|
@ -421,20 +418,20 @@ set(common_SRCS
|
||||||
serverlist.cpp
|
serverlist.cpp
|
||||||
serverobject.cpp
|
serverobject.cpp
|
||||||
settings.cpp
|
settings.cpp
|
||||||
|
sha1.cpp
|
||||||
socket.cpp
|
socket.cpp
|
||||||
sound.cpp
|
sound.cpp
|
||||||
staticobject.cpp
|
staticobject.cpp
|
||||||
subgame.cpp
|
subgame.cpp
|
||||||
|
test.cpp
|
||||||
tool.cpp
|
tool.cpp
|
||||||
treegen.cpp
|
treegen.cpp
|
||||||
version.cpp
|
version.cpp
|
||||||
voxel.cpp
|
voxel.cpp
|
||||||
voxelalgorithms.cpp
|
voxelalgorithms.cpp
|
||||||
${common_network_SRCS}
|
|
||||||
${JTHREAD_SRCS}
|
${JTHREAD_SRCS}
|
||||||
${common_SCRIPT_SRCS}
|
${common_SCRIPT_SRCS}
|
||||||
${UTIL_SRCS}
|
${UTIL_SRCS}
|
||||||
${unittests_SRCS}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# This gives us the icon and file version information
|
# This gives us the icon and file version information
|
||||||
|
@ -457,16 +454,9 @@ if(WIN32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Client sources
|
# Client sources
|
||||||
|
|
||||||
if (BUILD_CLIENT)
|
|
||||||
add_subdirectory(client)
|
|
||||||
endif(BUILD_CLIENT)
|
|
||||||
|
|
||||||
set(minetest_SRCS
|
set(minetest_SRCS
|
||||||
${common_SRCS}
|
${common_SRCS}
|
||||||
${sound_SRCS}
|
${sound_SRCS}
|
||||||
${client_SRCS}
|
|
||||||
${client_network_SRCS}
|
|
||||||
camera.cpp
|
camera.cpp
|
||||||
chat.cpp
|
chat.cpp
|
||||||
client.cpp
|
client.cpp
|
||||||
|
@ -499,6 +489,7 @@ set(minetest_SRCS
|
||||||
particles.cpp
|
particles.cpp
|
||||||
shader.cpp
|
shader.cpp
|
||||||
sky.cpp
|
sky.cpp
|
||||||
|
tile.cpp
|
||||||
wieldmesh.cpp
|
wieldmesh.cpp
|
||||||
${minetest_SCRIPT_SRCS}
|
${minetest_SCRIPT_SRCS}
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,22 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "irr_aabb3d.h"
|
#include "irr_aabb3d.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum ActiveObjectType {
|
#define ACTIVEOBJECT_TYPE_INVALID 0
|
||||||
ACTIVEOBJECT_TYPE_INVALID = 0,
|
|
||||||
ACTIVEOBJECT_TYPE_TEST = 1,
|
|
||||||
// Deprecated stuff
|
|
||||||
ACTIVEOBJECT_TYPE_ITEM = 2,
|
|
||||||
ACTIVEOBJECT_TYPE_RAT = 3,
|
|
||||||
ACTIVEOBJECT_TYPE_OERKKI1 = 4,
|
|
||||||
ACTIVEOBJECT_TYPE_FIREFLY = 5,
|
|
||||||
ACTIVEOBJECT_TYPE_MOBV2 = 6,
|
|
||||||
// End deprecated stuff
|
|
||||||
ACTIVEOBJECT_TYPE_LUAENTITY = 7,
|
|
||||||
// Special type, not stored as a static object
|
|
||||||
ACTIVEOBJECT_TYPE_PLAYER = 100,
|
|
||||||
// Special type, only exists as CAO
|
|
||||||
ACTIVEOBJECT_TYPE_GENERIC = 101,
|
|
||||||
};
|
|
||||||
// Other types are defined in content_object.h
|
// Other types are defined in content_object.h
|
||||||
|
|
||||||
struct ActiveObjectMessage
|
struct ActiveObjectMessage
|
||||||
|
@ -75,7 +60,7 @@ public:
|
||||||
m_id = id;
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ActiveObjectType getType() const = 0;
|
virtual u8 getType() const = 0;
|
||||||
virtual bool getCollisionBox(aabb3f *toset) = 0;
|
virtual bool getCollisionBox(aabb3f *toset) = 0;
|
||||||
virtual bool collideWithObjects() = 0;
|
virtual bool collideWithObjects() = 0;
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include <ICameraSceneNode.h>
|
#include <ICameraSceneNode.h>
|
||||||
|
|
||||||
|
|
466
src/cavegen.cpp
466
src/cavegen.cpp
|
@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
#include "mapgen_v5.h"
|
|
||||||
#include "mapgen_v6.h"
|
#include "mapgen_v6.h"
|
||||||
#include "mapgen_v7.h"
|
#include "mapgen_v7.h"
|
||||||
#include "cavegen.h"
|
#include "cavegen.h"
|
||||||
|
@ -28,263 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0);
|
NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0);
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////// Caves V5
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
CaveV5::CaveV5(MapgenV5 *mg, PseudoRandom *ps) {
|
|
||||||
this->mg = mg;
|
|
||||||
this->vm = mg->vm;
|
|
||||||
this->ndef = mg->ndef;
|
|
||||||
this->water_level = mg->water_level;
|
|
||||||
this->ps = ps;
|
|
||||||
this->c_water_source = mg->c_water_source;
|
|
||||||
this->c_lava_source = mg->c_lava_source;
|
|
||||||
this->c_ice = mg->c_ice;
|
|
||||||
this->np_caveliquids = &nparams_caveliquids;
|
|
||||||
|
|
||||||
dswitchint = ps->range(1, 14);
|
|
||||||
flooded = ps->range(1, 2) == 2;
|
|
||||||
|
|
||||||
part_max_length_rs = ps->range(2, 4);
|
|
||||||
tunnel_routepoints = ps->range(5, ps->range(15, 30));
|
|
||||||
min_tunnel_diameter = 5;
|
|
||||||
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
|
|
||||||
|
|
||||||
large_cave_is_flat = (ps->range(0, 1) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CaveV5::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
|
||||||
node_min = nmin;
|
|
||||||
node_max = nmax;
|
|
||||||
main_direction = v3f(0, 0, 0);
|
|
||||||
|
|
||||||
// Allowed route area size in nodes
|
|
||||||
ar = node_max - node_min + v3s16(1, 1, 1);
|
|
||||||
// Area starting point in nodes
|
|
||||||
of = node_min;
|
|
||||||
|
|
||||||
// Allow a bit more
|
|
||||||
//(this should be more than the maximum radius of the tunnel)
|
|
||||||
s16 insure = 10;
|
|
||||||
s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1);
|
|
||||||
ar += v3s16(1,0,1) * more * 2;
|
|
||||||
of -= v3s16(1,0,1) * more;
|
|
||||||
|
|
||||||
route_y_min = 0;
|
|
||||||
// Allow half a diameter + 7 over stone surface
|
|
||||||
route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7;
|
|
||||||
|
|
||||||
// Limit maximum to area
|
|
||||||
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
|
|
||||||
|
|
||||||
s16 min = 0;
|
|
||||||
if (node_min.Y < water_level && node_max.Y > water_level) {
|
|
||||||
min = water_level - max_tunnel_diameter/3 - of.Y;
|
|
||||||
route_y_max = water_level + max_tunnel_diameter/3 - of.Y;
|
|
||||||
}
|
|
||||||
route_y_min = ps->range(min, min + max_tunnel_diameter);
|
|
||||||
route_y_min = rangelim(route_y_min, 0, route_y_max);
|
|
||||||
|
|
||||||
s16 route_start_y_min = route_y_min;
|
|
||||||
s16 route_start_y_max = route_y_max;
|
|
||||||
|
|
||||||
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1);
|
|
||||||
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1);
|
|
||||||
|
|
||||||
// Randomize starting position
|
|
||||||
orp = v3f(
|
|
||||||
(float)(ps->next() % ar.X) + 0.5,
|
|
||||||
(float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5,
|
|
||||||
(float)(ps->next() % ar.Z) + 0.5
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add generation notify begin event
|
|
||||||
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
|
||||||
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
|
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
|
||||||
|
|
||||||
// Generate some tunnel starting from orp
|
|
||||||
for (u16 j = 0; j < tunnel_routepoints; j++)
|
|
||||||
makeTunnel(j % dswitchint == 0);
|
|
||||||
|
|
||||||
// Add generation notify end event
|
|
||||||
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
|
||||||
notifytype = GENNOTIFY_LARGECAVE_END;
|
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CaveV5::makeTunnel(bool dirswitch) {
|
|
||||||
|
|
||||||
// Randomize size
|
|
||||||
s16 min_d = min_tunnel_diameter;
|
|
||||||
s16 max_d = max_tunnel_diameter;
|
|
||||||
rs = ps->range(min_d, max_d);
|
|
||||||
s16 rs_part_max_length_rs = rs * part_max_length_rs;
|
|
||||||
|
|
||||||
v3s16 maxlen;
|
|
||||||
maxlen = v3s16(
|
|
||||||
rs_part_max_length_rs,
|
|
||||||
rs_part_max_length_rs / 2,
|
|
||||||
rs_part_max_length_rs
|
|
||||||
);
|
|
||||||
|
|
||||||
v3f vec;
|
|
||||||
// Jump downward sometimes
|
|
||||||
vec = v3f(
|
|
||||||
(float)(ps->next() % maxlen.X) - (float)maxlen.X / 2,
|
|
||||||
(float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2,
|
|
||||||
(float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2
|
|
||||||
);
|
|
||||||
|
|
||||||
// Do not make large caves that are above ground.
|
|
||||||
// It is only necessary to check the startpoint and endpoint.
|
|
||||||
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
|
||||||
v3s16 veci(vec.X, vec.Y, vec.Z);
|
|
||||||
v3s16 p;
|
|
||||||
|
|
||||||
p = orpi + veci + of + rs / 2;
|
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
|
||||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
|
||||||
s16 h = mg->heightmap[index];
|
|
||||||
if (h < p.Y)
|
|
||||||
return;
|
|
||||||
} else if (p.Y > water_level) {
|
|
||||||
return; // If it's not in our heightmap, use a simple heuristic
|
|
||||||
}
|
|
||||||
|
|
||||||
p = orpi + of + rs / 2;
|
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
|
||||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
|
||||||
s16 h = mg->heightmap[index];
|
|
||||||
if (h < p.Y)
|
|
||||||
return;
|
|
||||||
} else if (p.Y > water_level) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec += main_direction;
|
|
||||||
|
|
||||||
v3f rp = orp + vec;
|
|
||||||
if (rp.X < 0)
|
|
||||||
rp.X = 0;
|
|
||||||
else if (rp.X >= ar.X)
|
|
||||||
rp.X = ar.X - 1;
|
|
||||||
|
|
||||||
if (rp.Y < route_y_min)
|
|
||||||
rp.Y = route_y_min;
|
|
||||||
else if (rp.Y >= route_y_max)
|
|
||||||
rp.Y = route_y_max - 1;
|
|
||||||
|
|
||||||
if (rp.Z < 0)
|
|
||||||
rp.Z = 0;
|
|
||||||
else if (rp.Z >= ar.Z)
|
|
||||||
rp.Z = ar.Z - 1;
|
|
||||||
|
|
||||||
vec = rp - orp;
|
|
||||||
|
|
||||||
float veclen = vec.getLength();
|
|
||||||
if (veclen < 0.05)
|
|
||||||
veclen = 1.0;
|
|
||||||
|
|
||||||
// Every second section is rough
|
|
||||||
bool randomize_xz = (ps->range(1, 2) == 1);
|
|
||||||
|
|
||||||
// Make a ravine every once in a while if it's long enough
|
|
||||||
//float xylen = vec.X * vec.X + vec.Z * vec.Z;
|
|
||||||
//disable ravines for now
|
|
||||||
bool is_ravine = false; //(xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
|
|
||||||
|
|
||||||
// Carve routes
|
|
||||||
for (float f = 0; f < 1.0; f += 1.0 / veclen)
|
|
||||||
carveRoute(vec, f, randomize_xz, is_ravine);
|
|
||||||
|
|
||||||
orp = rp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|
||||||
MapNode airnode(CONTENT_AIR);
|
|
||||||
MapNode waternode(c_water_source);
|
|
||||||
MapNode lavanode(c_lava_source);
|
|
||||||
|
|
||||||
v3s16 startp(orp.X, orp.Y, orp.Z);
|
|
||||||
startp += of;
|
|
||||||
|
|
||||||
float nval = NoisePerlin3D(np_caveliquids, startp.X,
|
|
||||||
startp.Y, startp.Z, mg->seed);
|
|
||||||
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
|
|
||||||
|
|
||||||
v3f fp = orp + vec * f;
|
|
||||||
fp.X += 0.1 * ps->range(-10, 10);
|
|
||||||
fp.Z += 0.1 * ps->range(-10, 10);
|
|
||||||
v3s16 cp(fp.X, fp.Y, fp.Z);
|
|
||||||
|
|
||||||
s16 d0 = -rs/2;
|
|
||||||
s16 d1 = d0 + rs;
|
|
||||||
if (randomize_xz) {
|
|
||||||
d0 += ps->range(-1, 1);
|
|
||||||
d1 += ps->range(-1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
|
||||||
|
|
||||||
for (s16 z0 = d0; z0 <= d1; z0++) {
|
|
||||||
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
|
|
||||||
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
|
|
||||||
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
|
|
||||||
|
|
||||||
s16 si2 = is_ravine ? MYMIN(ps->range(25, 26), ar.Y) :
|
|
||||||
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
|
||||||
|
|
||||||
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
|
||||||
if (large_cave_is_flat) {
|
|
||||||
// Make large caves not so tall
|
|
||||||
if (rs > 7 && abs(y0) >= rs / 3)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
|
|
||||||
p += of;
|
|
||||||
|
|
||||||
if (!is_ravine && mg->heightmap && should_make_cave_hole &&
|
|
||||||
p.X <= node_max.X && p.Z <= node_max.Z) {
|
|
||||||
int maplen = node_max.X - node_min.X + 1;
|
|
||||||
int idx = (p.Z - node_min.Z) * maplen + (p.X - node_min.X);
|
|
||||||
if (p.Y >= mg->heightmap[idx] - 2)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vm->m_area.contains(p) == false)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u32 i = vm->m_area.index(p);
|
|
||||||
|
|
||||||
// Don't replace air, water, lava, or ice
|
|
||||||
content_t c = vm->m_data[i].getContent();
|
|
||||||
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR ||
|
|
||||||
c == c_water_source || c == c_lava_source || c == c_ice)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
|
||||||
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
if (flooded && full_ymin < water_level && full_ymax > water_level)
|
|
||||||
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
|
|
||||||
else if (flooded && full_ymax < water_level)
|
|
||||||
vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode;
|
|
||||||
else
|
|
||||||
vm->m_data[i] = airnode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////// Caves V6
|
|
||||||
|
|
||||||
|
|
||||||
CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_cave) {
|
CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_cave) {
|
||||||
|
@ -398,68 +141,37 @@ void CaveV6::makeTunnel(bool dirswitch) {
|
||||||
s16 min_d = min_tunnel_diameter;
|
s16 min_d = min_tunnel_diameter;
|
||||||
s16 max_d = max_tunnel_diameter;
|
s16 max_d = max_tunnel_diameter;
|
||||||
rs = ps->range(min_d, max_d);
|
rs = ps->range(min_d, max_d);
|
||||||
s16 rs_part_max_length_rs = rs * part_max_length_rs;
|
|
||||||
|
|
||||||
v3s16 maxlen;
|
v3s16 maxlen;
|
||||||
if (large_cave) {
|
if (large_cave) {
|
||||||
maxlen = v3s16(
|
maxlen = v3s16(
|
||||||
rs_part_max_length_rs,
|
rs * part_max_length_rs,
|
||||||
rs_part_max_length_rs / 2,
|
rs * part_max_length_rs / 2,
|
||||||
rs_part_max_length_rs
|
rs * part_max_length_rs
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
maxlen = v3s16(
|
maxlen = v3s16(
|
||||||
rs_part_max_length_rs,
|
rs * part_max_length_rs,
|
||||||
ps->range(1, rs_part_max_length_rs),
|
ps->range(1, rs * part_max_length_rs),
|
||||||
rs_part_max_length_rs
|
rs * part_max_length_rs
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
v3f vec(
|
v3f vec(
|
||||||
(float)(ps->next() % maxlen.X) - (float)maxlen.X / 2,
|
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
|
||||||
(float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2,
|
(float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2,
|
||||||
(float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2
|
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
|
||||||
);
|
);
|
||||||
|
|
||||||
// Jump downward sometimes
|
// Jump downward sometimes
|
||||||
if (!large_cave && ps->range(0, 12) == 0) {
|
if (!large_cave && ps->range(0, 12) == 0) {
|
||||||
vec = v3f(
|
vec = v3f(
|
||||||
(float)(ps->next() % maxlen.X) - (float)maxlen.X / 2,
|
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
|
||||||
(float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y,
|
(float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y,
|
||||||
(float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2
|
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not make large caves that are entirely above ground.
|
|
||||||
// It is only necessary to check the startpoint and endpoint.
|
|
||||||
if (large_cave) {
|
|
||||||
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
|
||||||
v3s16 veci(vec.X, vec.Y, vec.Z);
|
|
||||||
s16 h1;
|
|
||||||
s16 h2;
|
|
||||||
|
|
||||||
v3s16 p1 = orpi + veci + of + rs / 2;
|
|
||||||
if (p1.Z >= node_min.Z && p1.Z <= node_max.Z &&
|
|
||||||
p1.X >= node_min.X && p1.X <= node_max.X) {
|
|
||||||
u32 index1 = (p1.Z - node_min.Z) * mg->ystride + (p1.X - node_min.X);
|
|
||||||
h1 = mg->heightmap[index1];
|
|
||||||
} else {
|
|
||||||
h1 = water_level; // If not in heightmap
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 p2 = orpi + of + rs / 2;
|
|
||||||
if (p2.Z >= node_min.Z && p2.Z <= node_max.Z &&
|
|
||||||
p2.X >= node_min.X && p2.X <= node_max.X) {
|
|
||||||
u32 index2 = (p2.Z - node_min.Z) * mg->ystride + (p2.X - node_min.X);
|
|
||||||
h2 = mg->heightmap[index2];
|
|
||||||
} else {
|
|
||||||
h2 = water_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p1.Y > h1 && p2.Y > h2) // If startpoint and endpoint are above ground
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec += main_direction;
|
vec += main_direction;
|
||||||
|
|
||||||
v3f rp = orp + vec;
|
v3f rp = orp + vec;
|
||||||
|
@ -567,12 +279,12 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
|
||||||
|
|
||||||
///////////////////////////////////////// Caves V7
|
///////////////////////////////////////// Caves V7
|
||||||
|
|
||||||
|
CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
|
||||||
CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps) {
|
|
||||||
this->mg = mg;
|
this->mg = mg;
|
||||||
this->vm = mg->vm;
|
this->vm = mg->vm;
|
||||||
this->ndef = mg->ndef;
|
this->ndef = mg->ndef;
|
||||||
this->water_level = mg->water_level;
|
this->water_level = mg->water_level;
|
||||||
|
this->large_cave = is_large_cave;
|
||||||
this->ps = ps;
|
this->ps = ps;
|
||||||
this->c_water_source = mg->c_water_source;
|
this->c_water_source = mg->c_water_source;
|
||||||
this->c_lava_source = mg->c_lava_source;
|
this->c_lava_source = mg->c_lava_source;
|
||||||
|
@ -582,10 +294,17 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps) {
|
||||||
dswitchint = ps->range(1, 14);
|
dswitchint = ps->range(1, 14);
|
||||||
flooded = ps->range(1, 2) == 2;
|
flooded = ps->range(1, 2) == 2;
|
||||||
|
|
||||||
part_max_length_rs = ps->range(2, 4);
|
if (large_cave) {
|
||||||
tunnel_routepoints = ps->range(5, ps->range(15, 30));
|
part_max_length_rs = ps->range(2, 4);
|
||||||
min_tunnel_diameter = 5;
|
tunnel_routepoints = ps->range(5, ps->range(15, 30));
|
||||||
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
|
min_tunnel_diameter = 5;
|
||||||
|
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
|
||||||
|
} else {
|
||||||
|
part_max_length_rs = ps->range(2, 9);
|
||||||
|
tunnel_routepoints = ps->range(10, ps->range(15, 30));
|
||||||
|
min_tunnel_diameter = 2;
|
||||||
|
max_tunnel_diameter = ps->range(2, 6);
|
||||||
|
}
|
||||||
|
|
||||||
large_cave_is_flat = (ps->range(0, 1) == 0);
|
large_cave_is_flat = (ps->range(0, 1) == 0);
|
||||||
}
|
}
|
||||||
|
@ -616,13 +335,15 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
||||||
// Limit maximum to area
|
// Limit maximum to area
|
||||||
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
|
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
|
||||||
|
|
||||||
s16 min = 0;
|
if (large_cave) {
|
||||||
if (node_min.Y < water_level && node_max.Y > water_level) {
|
s16 min = 0;
|
||||||
min = water_level - max_tunnel_diameter/3 - of.Y;
|
if (node_min.Y < water_level && node_max.Y > water_level) {
|
||||||
route_y_max = water_level + max_tunnel_diameter/3 - of.Y;
|
min = water_level - max_tunnel_diameter/3 - of.Y;
|
||||||
|
route_y_max = water_level + max_tunnel_diameter/3 - of.Y;
|
||||||
|
}
|
||||||
|
route_y_min = ps->range(min, min + max_tunnel_diameter);
|
||||||
|
route_y_min = rangelim(route_y_min, 0, route_y_max);
|
||||||
}
|
}
|
||||||
route_y_min = ps->range(min, min + max_tunnel_diameter);
|
|
||||||
route_y_min = rangelim(route_y_min, 0, route_y_max);
|
|
||||||
|
|
||||||
s16 route_start_y_min = route_y_min;
|
s16 route_start_y_min = route_y_min;
|
||||||
s16 route_start_y_max = route_y_max;
|
s16 route_start_y_max = route_y_max;
|
||||||
|
@ -639,7 +360,8 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
||||||
|
|
||||||
// Add generation notify begin event
|
// Add generation notify begin event
|
||||||
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
|
GenNotifyType notifytype = large_cave ?
|
||||||
|
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
mg->gennotify.addEvent(notifytype, abs_pos);
|
||||||
|
|
||||||
// Generate some tunnel starting from orp
|
// Generate some tunnel starting from orp
|
||||||
|
@ -648,60 +370,86 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
||||||
|
|
||||||
// Add generation notify end event
|
// Add generation notify end event
|
||||||
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
notifytype = GENNOTIFY_LARGECAVE_END;
|
notifytype = large_cave ?
|
||||||
|
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
mg->gennotify.addEvent(notifytype, abs_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CaveV7::makeTunnel(bool dirswitch) {
|
void CaveV7::makeTunnel(bool dirswitch) {
|
||||||
|
if (dirswitch && !large_cave) {
|
||||||
|
main_direction = v3f(
|
||||||
|
((float)(ps->next() % 20) - (float)10) / 10,
|
||||||
|
((float)(ps->next() % 20) - (float)10) / 30,
|
||||||
|
((float)(ps->next() % 20) - (float)10) / 10
|
||||||
|
);
|
||||||
|
main_direction *= (float)ps->range(0, 10) / 10;
|
||||||
|
}
|
||||||
|
|
||||||
// Randomize size
|
// Randomize size
|
||||||
s16 min_d = min_tunnel_diameter;
|
s16 min_d = min_tunnel_diameter;
|
||||||
s16 max_d = max_tunnel_diameter;
|
s16 max_d = max_tunnel_diameter;
|
||||||
rs = ps->range(min_d, max_d);
|
rs = ps->range(min_d, max_d);
|
||||||
s16 rs_part_max_length_rs = rs * part_max_length_rs;
|
|
||||||
|
|
||||||
v3s16 maxlen;
|
v3s16 maxlen;
|
||||||
maxlen = v3s16(
|
if (large_cave) {
|
||||||
rs_part_max_length_rs,
|
maxlen = v3s16(
|
||||||
rs_part_max_length_rs / 2,
|
rs * part_max_length_rs,
|
||||||
rs_part_max_length_rs
|
rs * part_max_length_rs / 2,
|
||||||
);
|
rs * part_max_length_rs
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
maxlen = v3s16(
|
||||||
|
rs * part_max_length_rs,
|
||||||
|
ps->range(1, rs * part_max_length_rs),
|
||||||
|
rs * part_max_length_rs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
v3f vec;
|
v3f vec;
|
||||||
// Jump downward sometimes
|
// Jump downward sometimes
|
||||||
vec = v3f(
|
if (!large_cave && ps->range(0, 12) == 0) {
|
||||||
(float)(ps->next() % maxlen.X) - (float)maxlen.X / 2,
|
vec = v3f(
|
||||||
(float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2,
|
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
|
||||||
(float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2
|
(float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y,
|
||||||
);
|
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
vec = v3f(
|
||||||
|
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
|
||||||
|
(float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2,
|
||||||
|
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Do not make large caves that are above ground.
|
// Do not make large caves that are above ground.
|
||||||
// It is only necessary to check the startpoint and endpoint.
|
// It is only necessary to check the startpoint and endpoint.
|
||||||
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
if (large_cave) {
|
||||||
v3s16 veci(vec.X, vec.Y, vec.Z);
|
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
||||||
v3s16 p;
|
v3s16 veci(vec.X, vec.Y, vec.Z);
|
||||||
|
v3s16 p;
|
||||||
|
|
||||||
p = orpi + veci + of + rs / 2;
|
p = orpi + veci + of + rs / 2;
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
p.X >= node_min.X && p.X <= node_max.X) {
|
||||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
||||||
s16 h = mg->ridge_heightmap[index];
|
s16 h = mg->ridge_heightmap[index];
|
||||||
if (h < p.Y)
|
if (h < p.Y)
|
||||||
return;
|
return;
|
||||||
} else if (p.Y > water_level) {
|
} else if (p.Y > water_level) {
|
||||||
return; // If it's not in our heightmap, use a simple heuristic
|
return; // If it's not in our heightmap, use a simple heuristic
|
||||||
}
|
}
|
||||||
|
|
||||||
p = orpi + of + rs / 2;
|
p = orpi + of + rs / 2;
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
p.X >= node_min.X && p.X <= node_max.X) {
|
||||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
||||||
s16 h = mg->ridge_heightmap[index];
|
s16 h = mg->ridge_heightmap[index];
|
||||||
if (h < p.Y)
|
if (h < p.Y)
|
||||||
|
return;
|
||||||
|
} else if (p.Y > water_level) {
|
||||||
return;
|
return;
|
||||||
} else if (p.Y > water_level) {
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec += main_direction;
|
vec += main_direction;
|
||||||
|
@ -754,7 +502,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
||||||
|
|
||||||
float nval = NoisePerlin3D(np_caveliquids, startp.X,
|
float nval = NoisePerlin3D(np_caveliquids, startp.X,
|
||||||
startp.Y, startp.Z, mg->seed);
|
startp.Y, startp.Z, mg->seed);
|
||||||
MapNode liquidnode = (nval < 0.40 && node_max.Y < -256) ? lavanode : waternode;
|
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
|
||||||
|
|
||||||
v3f fp = orp + vec * f;
|
v3f fp = orp + vec * f;
|
||||||
fp.X += 0.1 * ps->range(-10, 10);
|
fp.X += 0.1 * ps->range(-10, 10);
|
||||||
|
@ -768,6 +516,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
||||||
d1 += ps->range(-1, 1);
|
d1 += ps->range(-1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
|
||||||
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
||||||
|
|
||||||
for (s16 z0 = d0; z0 <= d1; z0++) {
|
for (s16 z0 = d0; z0 <= d1; z0++) {
|
||||||
|
@ -779,6 +528,10 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
||||||
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
||||||
|
|
||||||
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
||||||
|
// Make better floors in small caves
|
||||||
|
if(flat_cave_floor && y0 <= -rs/2 && rs<=7)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (large_cave_is_flat) {
|
if (large_cave_is_flat) {
|
||||||
// Make large caves not so tall
|
// Make large caves not so tall
|
||||||
if (rs > 7 && abs(y0) >= rs / 3)
|
if (rs > 7 && abs(y0) >= rs / 3)
|
||||||
|
@ -807,17 +560,24 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
||||||
c == c_water_source || c == c_lava_source || c == c_ice)
|
c == c_water_source || c == c_lava_source || c == c_ice)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
if (large_cave) {
|
||||||
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
||||||
|
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
if (flooded && full_ymin < water_level && full_ymax > water_level)
|
||||||
|
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
|
||||||
|
else if (flooded && full_ymax < water_level)
|
||||||
|
vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode;
|
||||||
|
else
|
||||||
|
vm->m_data[i] = airnode;
|
||||||
|
} else {
|
||||||
|
if (c == CONTENT_IGNORE)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (flooded && full_ymin < water_level && full_ymax > water_level)
|
|
||||||
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
|
|
||||||
else if (flooded && full_ymax < water_level)
|
|
||||||
vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode;
|
|
||||||
else
|
|
||||||
vm->m_data[i] = airnode;
|
vm->m_data[i] = airnode;
|
||||||
|
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,55 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
|
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
|
||||||
|
|
||||||
class MapgenV5;
|
|
||||||
class MapgenV6;
|
class MapgenV6;
|
||||||
class MapgenV7;
|
class MapgenV7;
|
||||||
|
|
||||||
class CaveV5 {
|
|
||||||
public:
|
|
||||||
MapgenV5 *mg;
|
|
||||||
MMVManip *vm;
|
|
||||||
INodeDefManager *ndef;
|
|
||||||
|
|
||||||
NoiseParams *np_caveliquids;
|
|
||||||
|
|
||||||
s16 min_tunnel_diameter;
|
|
||||||
s16 max_tunnel_diameter;
|
|
||||||
u16 tunnel_routepoints;
|
|
||||||
int dswitchint;
|
|
||||||
int part_max_length_rs;
|
|
||||||
|
|
||||||
bool large_cave_is_flat;
|
|
||||||
bool flooded;
|
|
||||||
|
|
||||||
s16 max_stone_y;
|
|
||||||
v3s16 node_min;
|
|
||||||
v3s16 node_max;
|
|
||||||
|
|
||||||
v3f orp; // starting point, relative to caved space
|
|
||||||
v3s16 of; // absolute coordinates of caved space
|
|
||||||
v3s16 ar; // allowed route area
|
|
||||||
s16 rs; // tunnel radius size
|
|
||||||
v3f main_direction;
|
|
||||||
|
|
||||||
s16 route_y_min;
|
|
||||||
s16 route_y_max;
|
|
||||||
|
|
||||||
PseudoRandom *ps;
|
|
||||||
|
|
||||||
content_t c_water_source;
|
|
||||||
content_t c_lava_source;
|
|
||||||
content_t c_ice;
|
|
||||||
|
|
||||||
int water_level;
|
|
||||||
|
|
||||||
CaveV5() {}
|
|
||||||
CaveV5(MapgenV5 *mg, PseudoRandom *ps);
|
|
||||||
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
|
|
||||||
void makeTunnel(bool dirswitch);
|
|
||||||
void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CaveV6 {
|
class CaveV6 {
|
||||||
public:
|
public:
|
||||||
MapgenV6 *mg;
|
MapgenV6 *mg;
|
||||||
|
@ -129,6 +83,7 @@ public:
|
||||||
int dswitchint;
|
int dswitchint;
|
||||||
int part_max_length_rs;
|
int part_max_length_rs;
|
||||||
|
|
||||||
|
bool large_cave;
|
||||||
bool large_cave_is_flat;
|
bool large_cave_is_flat;
|
||||||
bool flooded;
|
bool flooded;
|
||||||
|
|
||||||
|
@ -154,7 +109,7 @@ public:
|
||||||
int water_level;
|
int water_level;
|
||||||
|
|
||||||
CaveV7() {}
|
CaveV7() {}
|
||||||
CaveV7(MapgenV7 *mg, PseudoRandom *ps);
|
CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool large_cave);
|
||||||
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
|
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
|
||||||
void makeTunnel(bool dirswitch);
|
void makeTunnel(bool dirswitch);
|
||||||
void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine);
|
void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine);
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <irrlicht.h>
|
#include <irrlicht.h>
|
||||||
#include <iostream>
|
|
||||||
#include "CGUITTFont.h"
|
#include "CGUITTFont.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
|
@ -65,24 +64,8 @@ scene::SMesh CGUITTFont::shared_plane_;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
/** Checks that no dimension of the FT_BitMap object is negative. If either is
|
|
||||||
* negative, abort execution.
|
|
||||||
*/
|
|
||||||
inline void checkFontBitmapSize(const FT_Bitmap &bits)
|
|
||||||
{
|
|
||||||
if ((s32)bits.rows < 0 || (s32)bits.width < 0) {
|
|
||||||
std::cout << "Insane font glyph size. File: "
|
|
||||||
<< __FILE__ << " Line " << __LINE__
|
|
||||||
<< std::endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const
|
video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const
|
||||||
{
|
{
|
||||||
// Make sure our casts to s32 in the loops below will not cause problems
|
|
||||||
checkFontBitmapSize(bits);
|
|
||||||
|
|
||||||
// Determine what our texture size should be.
|
// Determine what our texture size should be.
|
||||||
// Add 1 because textures are inclusive-exclusive.
|
// Add 1 because textures are inclusive-exclusive.
|
||||||
core::dimension2du d(bits.width + 1, bits.rows + 1);
|
core::dimension2du d(bits.width + 1, bits.rows + 1);
|
||||||
|
@ -104,11 +87,10 @@ video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVide
|
||||||
const u32 image_pitch = image->getPitch() / sizeof(u16);
|
const u32 image_pitch = image->getPitch() / sizeof(u16);
|
||||||
u16* image_data = (u16*)image->lock();
|
u16* image_data = (u16*)image->lock();
|
||||||
u8* glyph_data = bits.buffer;
|
u8* glyph_data = bits.buffer;
|
||||||
|
for (int y = 0; y < bits.rows; ++y)
|
||||||
for (s32 y = 0; y < (s32)bits.rows; ++y)
|
|
||||||
{
|
{
|
||||||
u16* row = image_data;
|
u16* row = image_data;
|
||||||
for (s32 x = 0; x < (s32)bits.width; ++x)
|
for (int x = 0; x < bits.width; ++x)
|
||||||
{
|
{
|
||||||
// Monochrome bitmaps store 8 pixels per byte. The left-most pixel is the bit 0x80.
|
// Monochrome bitmaps store 8 pixels per byte. The left-most pixel is the bit 0x80.
|
||||||
// So, we go through the data each bit at a time.
|
// So, we go through the data each bit at a time.
|
||||||
|
@ -134,10 +116,10 @@ video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVide
|
||||||
const u32 image_pitch = image->getPitch() / sizeof(u32);
|
const u32 image_pitch = image->getPitch() / sizeof(u32);
|
||||||
u32* image_data = (u32*)image->lock();
|
u32* image_data = (u32*)image->lock();
|
||||||
u8* glyph_data = bits.buffer;
|
u8* glyph_data = bits.buffer;
|
||||||
for (s32 y = 0; y < (s32)bits.rows; ++y)
|
for (int y = 0; y < bits.rows; ++y)
|
||||||
{
|
{
|
||||||
u8* row = glyph_data;
|
u8* row = glyph_data;
|
||||||
for (s32 x = 0; x < (s32)bits.width; ++x)
|
for (int x = 0; x < bits.width; ++x)
|
||||||
{
|
{
|
||||||
image_data[y * image_pitch + x] |= static_cast<u32>(255.0f * (static_cast<float>(*row++) / gray_count)) << 24;
|
image_data[y * image_pitch + x] |= static_cast<u32>(255.0f * (static_cast<float>(*row++) / gray_count)) << 24;
|
||||||
//data[y * image_pitch + x] |= ((u32)(*bitsdata++) << 24);
|
//data[y * image_pitch + x] |= ((u32)(*bitsdata++) << 24);
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#define __BYTE_ORDER 0
|
#define __BYTE_ORDER 0
|
||||||
#define __LITTLE_ENDIAN 0
|
#define __LITTLE_ENDIAN 0
|
||||||
#define __BIG_ENDIAN 1
|
#define __BIG_ENDIAN 1
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif __MACH__
|
||||||
#include <machine/endian.h>
|
#include <machine/endian.h>
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
#include <sys/endian.h>
|
#include <sys/endian.h>
|
||||||
|
|
1691
src/client.cpp
1691
src/client.cpp
File diff suppressed because it is too large
Load Diff
71
src/client.h
71
src/client.h
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#ifndef CLIENT_HEADER
|
#ifndef CLIENT_HEADER
|
||||||
#define CLIENT_HEADER
|
#define CLIENT_HEADER
|
||||||
|
|
||||||
#include "network/connection.h"
|
#include "connection.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "jthread/jmutex.h"
|
#include "jthread/jmutex.h"
|
||||||
|
@ -34,7 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "particles.h"
|
#include "particles.h"
|
||||||
#include "network/networkpacket.h"
|
|
||||||
|
|
||||||
struct MeshMakeData;
|
struct MeshMakeData;
|
||||||
class MapBlockMesh;
|
class MapBlockMesh;
|
||||||
|
@ -48,6 +47,7 @@ struct MapDrawControl;
|
||||||
class MtEventManager;
|
class MtEventManager;
|
||||||
struct PointedThing;
|
struct PointedThing;
|
||||||
class Database;
|
class Database;
|
||||||
|
class Server;
|
||||||
|
|
||||||
struct QueuedMeshUpdate
|
struct QueuedMeshUpdate
|
||||||
{
|
{
|
||||||
|
@ -341,61 +341,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void step(float dtime);
|
void step(float dtime);
|
||||||
|
|
||||||
/*
|
|
||||||
* Command Handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
void handleCommand(NetworkPacket* pkt);
|
|
||||||
|
|
||||||
void handleCommand_Null(NetworkPacket* pkt) {};
|
|
||||||
void handleCommand_Deprecated(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Init(NetworkPacket* pkt);
|
|
||||||
void handleCommand_AccessDenied(NetworkPacket* pkt);
|
|
||||||
void handleCommand_RemoveNode(NetworkPacket* pkt);
|
|
||||||
void handleCommand_AddNode(NetworkPacket* pkt);
|
|
||||||
void handleCommand_BlockData(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Inventory(NetworkPacket* pkt);
|
|
||||||
void handleCommand_TimeOfDay(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ChatMessage(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Movement(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HP(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Breath(NetworkPacket* pkt);
|
|
||||||
void handleCommand_MovePlayer(NetworkPacket* pkt);
|
|
||||||
void handleCommand_PlayerItem(NetworkPacket* pkt);
|
|
||||||
void handleCommand_DeathScreen(NetworkPacket* pkt);
|
|
||||||
void handleCommand_AnnounceMedia(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Media(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ToolDef(NetworkPacket* pkt);
|
|
||||||
void handleCommand_NodeDef(NetworkPacket* pkt);
|
|
||||||
void handleCommand_CraftItemDef(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ItemDef(NetworkPacket* pkt);
|
|
||||||
void handleCommand_PlaySound(NetworkPacket* pkt);
|
|
||||||
void handleCommand_StopSound(NetworkPacket* pkt);
|
|
||||||
void handleCommand_Privileges(NetworkPacket* pkt);
|
|
||||||
void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
|
|
||||||
void handleCommand_DetachedInventory(NetworkPacket* pkt);
|
|
||||||
void handleCommand_ShowFormSpec(NetworkPacket* pkt);
|
|
||||||
void handleCommand_SpawnParticle(NetworkPacket* pkt);
|
|
||||||
void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
|
|
||||||
void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudAdd(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudRemove(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudChange(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudSetFlags(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudSetParam(NetworkPacket* pkt);
|
|
||||||
void handleCommand_HudSetSky(NetworkPacket* pkt);
|
|
||||||
void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
|
|
||||||
void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
|
|
||||||
void handleCommand_EyeOffset(NetworkPacket* pkt);
|
|
||||||
|
|
||||||
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
|
||||||
// Returns true if something was received
|
// Returns true if something was received
|
||||||
bool AsyncProcessPacket();
|
bool AsyncProcessPacket();
|
||||||
bool AsyncProcessData();
|
bool AsyncProcessData();
|
||||||
void Send(NetworkPacket* pkt);
|
void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
|
|
||||||
void interact(u8 action, const PointedThing& pointed);
|
void interact(u8 action, const PointedThing& pointed);
|
||||||
|
|
||||||
|
@ -515,7 +465,7 @@ public:
|
||||||
// Insert a media file appropriately into the appropriate manager
|
// Insert a media file appropriately into the appropriate manager
|
||||||
bool loadMedia(const std::string &data, const std::string &filename);
|
bool loadMedia(const std::string &data, const std::string &filename);
|
||||||
// Send a request for conventional media transfer
|
// Send a request for conventional media transfer
|
||||||
void request_media(const std::vector<std::string> &file_requests);
|
void request_media(const std::list<std::string> &file_requests);
|
||||||
// Send a notification that no conventional media transfer is needed
|
// Send a notification that no conventional media transfer is needed
|
||||||
void received_media();
|
void received_media();
|
||||||
|
|
||||||
|
@ -577,13 +527,13 @@ private:
|
||||||
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
||||||
//s32 m_daynight_i;
|
//s32 m_daynight_i;
|
||||||
//u32 m_daynight_ratio;
|
//u32 m_daynight_ratio;
|
||||||
std::queue<std::wstring> m_chat_queue;
|
Queue<std::wstring> m_chat_queue;
|
||||||
// The seed returned by the server in TOCLIENT_INIT is stored here
|
// The seed returned by the server in TOCLIENT_INIT is stored here
|
||||||
u64 m_map_seed;
|
u64 m_map_seed;
|
||||||
std::string m_password;
|
std::string m_password;
|
||||||
bool m_access_denied;
|
bool m_access_denied;
|
||||||
std::wstring m_access_denied_reason;
|
std::wstring m_access_denied_reason;
|
||||||
std::queue<ClientEvent> m_client_event_queue;
|
Queue<ClientEvent> m_client_event_queue;
|
||||||
bool m_itemdef_received;
|
bool m_itemdef_received;
|
||||||
bool m_nodedef_received;
|
bool m_nodedef_received;
|
||||||
ClientMediaDownloader *m_media_downloader;
|
ClientMediaDownloader *m_media_downloader;
|
||||||
|
@ -619,13 +569,12 @@ private:
|
||||||
LocalClientState m_state;
|
LocalClientState m_state;
|
||||||
|
|
||||||
// Used for saving server map to disk client-side
|
// Used for saving server map to disk client-side
|
||||||
Database *m_localdb;
|
Database *localdb;
|
||||||
IntervalLimiter m_localdb_save_interval;
|
Server *localserver;
|
||||||
u16 m_cache_save_interval;
|
|
||||||
|
|
||||||
// TODO: Add callback to update these when g_settings changes
|
// TODO: Add callback to update this when g_settings changes
|
||||||
bool m_cache_smooth_lighting;
|
bool m_cache_smooth_lighting;
|
||||||
bool m_cache_enable_shaders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !CLIENT_HEADER
|
#endif // !CLIENT_HEADER
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
set(client_SRCS
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp
|
|
||||||
PARENT_SCOPE
|
|
||||||
)
|
|
|
@ -1,709 +0,0 @@
|
||||||
/*
|
|
||||||
Minetest
|
|
||||||
Copyright (C) 2010-2013 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 "main.h"
|
|
||||||
#include "mainmenumanager.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "clouds.h"
|
|
||||||
#include "server.h"
|
|
||||||
#include "filesys.h"
|
|
||||||
#include "guiMainMenu.h"
|
|
||||||
#include "game.h"
|
|
||||||
#include "chat.h"
|
|
||||||
#include "gettext.h"
|
|
||||||
#include "profiler.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "serverlist.h"
|
|
||||||
#include "guiEngine.h"
|
|
||||||
#include "player.h"
|
|
||||||
#include "fontengine.h"
|
|
||||||
#include "clientlauncher.h"
|
|
||||||
|
|
||||||
// A pointer to a global instance of the time getter
|
|
||||||
// TODO: why?
|
|
||||||
TimeGetter *g_timegetter = NULL;
|
|
||||||
|
|
||||||
u32 getTimeMs()
|
|
||||||
{
|
|
||||||
if (g_timegetter == NULL)
|
|
||||||
return 0;
|
|
||||||
return g_timegetter->getTime(PRECISION_MILLI);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 getTime(TimePrecision prec) {
|
|
||||||
if (g_timegetter == NULL)
|
|
||||||
return 0;
|
|
||||||
return g_timegetter->getTime(prec);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientLauncher::~ClientLauncher()
|
|
||||||
{
|
|
||||||
if (receiver)
|
|
||||||
delete receiver;
|
|
||||||
|
|
||||||
if (input)
|
|
||||||
delete input;
|
|
||||||
|
|
||||||
if (g_fontengine)
|
|
||||||
delete g_fontengine;
|
|
||||||
|
|
||||||
if (device)
|
|
||||||
device->drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
|
|
||||||
{
|
|
||||||
init_args(game_params, cmd_args);
|
|
||||||
|
|
||||||
// List video modes if requested
|
|
||||||
if (list_video_modes)
|
|
||||||
return print_video_modes();
|
|
||||||
|
|
||||||
if (!init_engine(game_params.log_level)) {
|
|
||||||
errorstream << "Could not initialize game engine." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speed tests (done after irrlicht is loaded to get timer)
|
|
||||||
if (cmd_args.getFlag("speedtests")) {
|
|
||||||
dstream << "Running speed tests" << std::endl;
|
|
||||||
speed_tests();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
video::IVideoDriver *video_driver = device->getVideoDriver();
|
|
||||||
if (video_driver == NULL) {
|
|
||||||
errorstream << "Could not initialize video driver." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
porting::setXorgClassHint(video_driver->getExposedVideoData(), "Minetest");
|
|
||||||
|
|
||||||
/*
|
|
||||||
This changes the minimum allowed number of vertices in a VBO.
|
|
||||||
Default is 500.
|
|
||||||
*/
|
|
||||||
//driver->setMinHardwareBufferVertexCount(50);
|
|
||||||
|
|
||||||
// Create time getter
|
|
||||||
g_timegetter = new IrrlichtTimeGetter(device);
|
|
||||||
|
|
||||||
// Create game callback for menus
|
|
||||||
g_gamecallback = new MainGameCallback(device);
|
|
||||||
|
|
||||||
device->setResizable(true);
|
|
||||||
|
|
||||||
if (random_input)
|
|
||||||
input = new RandomInputHandler();
|
|
||||||
else
|
|
||||||
input = new RealInputHandler(device, receiver);
|
|
||||||
|
|
||||||
smgr = device->getSceneManager();
|
|
||||||
smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
|
|
||||||
|
|
||||||
guienv = device->getGUIEnvironment();
|
|
||||||
skin = guienv->getSkin();
|
|
||||||
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
|
|
||||||
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
|
|
||||||
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
|
|
||||||
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
|
|
||||||
skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
|
|
||||||
skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
|
|
||||||
|
|
||||||
g_fontengine = new FontEngine(g_settings, guienv);
|
|
||||||
assert(g_fontengine != NULL);
|
|
||||||
|
|
||||||
#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
|
|
||||||
// Irrlicht 1.8 input colours
|
|
||||||
skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
|
|
||||||
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Create the menu clouds
|
|
||||||
if (!g_menucloudsmgr)
|
|
||||||
g_menucloudsmgr = smgr->createNewSceneManager();
|
|
||||||
if (!g_menuclouds)
|
|
||||||
g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(),
|
|
||||||
g_menucloudsmgr, -1, rand(), 100);
|
|
||||||
g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255));
|
|
||||||
scene::ICameraSceneNode* camera;
|
|
||||||
camera = g_menucloudsmgr->addCameraSceneNode(0,
|
|
||||||
v3f(0, 0, 0), v3f(0, 60, 100));
|
|
||||||
camera->setFarValue(10000);
|
|
||||||
|
|
||||||
/*
|
|
||||||
GUI stuff
|
|
||||||
*/
|
|
||||||
|
|
||||||
ChatBackend chat_backend;
|
|
||||||
|
|
||||||
// If an error occurs, this is set to something by menu().
|
|
||||||
// It is then displayed before the menu shows on the next call to menu()
|
|
||||||
std::wstring error_message = L"";
|
|
||||||
|
|
||||||
bool first_loop = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Menu-game loop
|
|
||||||
*/
|
|
||||||
bool retval = true;
|
|
||||||
bool *kill = porting::signal_handler_killstatus();
|
|
||||||
|
|
||||||
while (device->run() && !*kill && !g_gamecallback->shutdown_requested)
|
|
||||||
{
|
|
||||||
// Set the window caption
|
|
||||||
const wchar_t *text = wgettext("Main Menu");
|
|
||||||
device->setWindowCaption((std::wstring(L"Minetest [") + text + L"]").c_str());
|
|
||||||
delete[] text;
|
|
||||||
|
|
||||||
try { // This is used for catching disconnects
|
|
||||||
|
|
||||||
guienv->clear();
|
|
||||||
|
|
||||||
/*
|
|
||||||
We need some kind of a root node to be able to add
|
|
||||||
custom gui elements directly on the screen.
|
|
||||||
Otherwise they won't be automatically drawn.
|
|
||||||
*/
|
|
||||||
guiroot = guienv->addStaticText(L"", core::rect<s32>(0, 0, 10000, 10000));
|
|
||||||
|
|
||||||
bool game_has_run = launch_game(&error_message, game_params, cmd_args);
|
|
||||||
|
|
||||||
// If skip_main_menu, we only want to startup once
|
|
||||||
if (skip_main_menu && !first_loop)
|
|
||||||
break;
|
|
||||||
|
|
||||||
first_loop = false;
|
|
||||||
|
|
||||||
if (!game_has_run) {
|
|
||||||
if (skip_main_menu)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Break out of menu-game loop to shut down cleanly
|
|
||||||
if (!device->run() || *kill) {
|
|
||||||
if (g_settings_path != "")
|
|
||||||
g_settings->updateConfigFile(g_settings_path.c_str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_playername.length() > PLAYERNAME_SIZE-1) {
|
|
||||||
error_message = wgettext("Player name too long.");
|
|
||||||
playername = current_playername.substr(0, PLAYERNAME_SIZE-1);
|
|
||||||
g_settings->set("name", playername);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
device->getVideoDriver()->setTextureCreationFlag(
|
|
||||||
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
|
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
receiver->m_touchscreengui = new TouchScreenGUI(device, receiver);
|
|
||||||
g_touchscreengui = receiver->m_touchscreengui;
|
|
||||||
#endif
|
|
||||||
the_game(
|
|
||||||
kill,
|
|
||||||
random_input,
|
|
||||||
input,
|
|
||||||
device,
|
|
||||||
worldspec.path,
|
|
||||||
current_playername,
|
|
||||||
current_password,
|
|
||||||
current_address,
|
|
||||||
current_port,
|
|
||||||
error_message,
|
|
||||||
chat_backend,
|
|
||||||
gamespec,
|
|
||||||
simple_singleplayer_mode
|
|
||||||
);
|
|
||||||
smgr->clear();
|
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
delete g_touchscreengui;
|
|
||||||
g_touchscreengui = NULL;
|
|
||||||
receiver->m_touchscreengui = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} //try
|
|
||||||
catch (con::PeerNotFoundException &e) {
|
|
||||||
error_message = wgettext("Connection error (timed out?)");
|
|
||||||
errorstream << wide_to_narrow(error_message) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
catch (std::exception &e) {
|
|
||||||
std::string narrow_message = "Some exception: \"";
|
|
||||||
narrow_message += e.what();
|
|
||||||
narrow_message += "\"";
|
|
||||||
errorstream << narrow_message << std::endl;
|
|
||||||
error_message = narrow_to_wide(narrow_message);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If no main menu, show error and exit
|
|
||||||
if (skip_main_menu) {
|
|
||||||
if (error_message != L"") {
|
|
||||||
verbosestream << "error_message = "
|
|
||||||
<< wide_to_narrow(error_message) << std::endl;
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // Menu-game loop
|
|
||||||
|
|
||||||
g_menuclouds->drop();
|
|
||||||
g_menucloudsmgr->drop();
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientLauncher::init_args(GameParams &game_params, const Settings &cmd_args)
|
|
||||||
{
|
|
||||||
|
|
||||||
skip_main_menu = cmd_args.getFlag("go");
|
|
||||||
|
|
||||||
// FIXME: This is confusing (but correct)
|
|
||||||
|
|
||||||
/* If world_path is set then override it unless skipping the main menu using
|
|
||||||
* the --go command line param. Else, give preference to the address
|
|
||||||
* supplied on the command line
|
|
||||||
*/
|
|
||||||
address = g_settings->get("address");
|
|
||||||
if (game_params.world_path != "" && !skip_main_menu)
|
|
||||||
address = "";
|
|
||||||
else if (cmd_args.exists("address"))
|
|
||||||
address = cmd_args.get("address");
|
|
||||||
|
|
||||||
playername = g_settings->get("name");
|
|
||||||
if (cmd_args.exists("name"))
|
|
||||||
playername = cmd_args.get("name");
|
|
||||||
|
|
||||||
list_video_modes = cmd_args.getFlag("videomodes");
|
|
||||||
|
|
||||||
use_freetype = g_settings->getBool("freetype");
|
|
||||||
|
|
||||||
random_input = g_settings->getBool("random_input")
|
|
||||||
|| cmd_args.getFlag("random-input");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientLauncher::init_engine(int log_level)
|
|
||||||
{
|
|
||||||
receiver = new MyEventReceiver();
|
|
||||||
create_engine_device(log_level);
|
|
||||||
return device != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientLauncher::launch_game(std::wstring *error_message,
|
|
||||||
GameParams &game_params, const Settings &cmd_args)
|
|
||||||
{
|
|
||||||
// Initialize menu data
|
|
||||||
MainMenuData menudata;
|
|
||||||
menudata.address = address;
|
|
||||||
menudata.name = playername;
|
|
||||||
menudata.port = itos(game_params.socket_port);
|
|
||||||
menudata.errormessage = wide_to_narrow(*error_message);
|
|
||||||
|
|
||||||
*error_message = L"";
|
|
||||||
|
|
||||||
if (cmd_args.exists("password"))
|
|
||||||
menudata.password = cmd_args.get("password");
|
|
||||||
|
|
||||||
menudata.enable_public = g_settings->getBool("server_announce");
|
|
||||||
|
|
||||||
// If a world was commanded, append and select it
|
|
||||||
if (game_params.world_path != "") {
|
|
||||||
worldspec.gameid = getWorldGameId(game_params.world_path, true);
|
|
||||||
worldspec.name = _("[--world parameter]");
|
|
||||||
|
|
||||||
if (worldspec.gameid == "") { // Create new
|
|
||||||
worldspec.gameid = g_settings->get("default_game");
|
|
||||||
worldspec.name += " [new]";
|
|
||||||
}
|
|
||||||
worldspec.path = game_params.world_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show the GUI menu
|
|
||||||
*/
|
|
||||||
if (!skip_main_menu) {
|
|
||||||
main_menu(&menudata);
|
|
||||||
|
|
||||||
// Skip further loading if there was an exit signal.
|
|
||||||
if (*porting::signal_handler_killstatus())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
address = menudata.address;
|
|
||||||
int newport = stoi(menudata.port);
|
|
||||||
if (newport != 0)
|
|
||||||
game_params.socket_port = newport;
|
|
||||||
|
|
||||||
simple_singleplayer_mode = menudata.simple_singleplayer_mode;
|
|
||||||
|
|
||||||
std::vector<WorldSpec> worldspecs = getAvailableWorlds();
|
|
||||||
|
|
||||||
if (menudata.selected_world >= 0
|
|
||||||
&& menudata.selected_world < (int)worldspecs.size()) {
|
|
||||||
g_settings->set("selected_world_path",
|
|
||||||
worldspecs[menudata.selected_world].path);
|
|
||||||
worldspec = worldspecs[menudata.selected_world];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menudata.errormessage != "") {
|
|
||||||
/* The calling function will pass this back into this function upon the
|
|
||||||
* next iteration (if any) causing it to be displayed by the GUI
|
|
||||||
*/
|
|
||||||
*error_message = narrow_to_wide(menudata.errormessage);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menudata.name == "")
|
|
||||||
menudata.name = std::string("Guest") + itos(myrand_range(1000, 9999));
|
|
||||||
else
|
|
||||||
playername = menudata.name;
|
|
||||||
|
|
||||||
password = translatePassword(playername, narrow_to_wide(menudata.password));
|
|
||||||
|
|
||||||
g_settings->set("name", playername);
|
|
||||||
|
|
||||||
current_playername = playername;
|
|
||||||
current_password = password;
|
|
||||||
current_address = address;
|
|
||||||
current_port = game_params.socket_port;
|
|
||||||
|
|
||||||
// If using simple singleplayer mode, override
|
|
||||||
if (simple_singleplayer_mode) {
|
|
||||||
assert(skip_main_menu == false);
|
|
||||||
current_playername = "singleplayer";
|
|
||||||
current_password = "";
|
|
||||||
current_address = "";
|
|
||||||
current_port = myrand_range(49152, 65535);
|
|
||||||
} else if (address != "") {
|
|
||||||
ServerListSpec server;
|
|
||||||
server["name"] = menudata.servername;
|
|
||||||
server["address"] = menudata.address;
|
|
||||||
server["port"] = menudata.port;
|
|
||||||
server["description"] = menudata.serverdescription;
|
|
||||||
ServerList::insert(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
infostream << "Selected world: " << worldspec.name
|
|
||||||
<< " [" << worldspec.path << "]" << std::endl;
|
|
||||||
|
|
||||||
if (current_address == "") { // If local game
|
|
||||||
if (worldspec.path == "") {
|
|
||||||
*error_message = wgettext("No world selected and no address "
|
|
||||||
"provided. Nothing to do.");
|
|
||||||
errorstream << wide_to_narrow(*error_message) << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs::PathExists(worldspec.path)) {
|
|
||||||
*error_message = wgettext("Provided world path doesn't exist: ")
|
|
||||||
+ narrow_to_wide(worldspec.path);
|
|
||||||
errorstream << wide_to_narrow(*error_message) << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load gamespec for required game
|
|
||||||
gamespec = findWorldSubgame(worldspec.path);
|
|
||||||
if (!gamespec.isValid() && !game_params.game_spec.isValid()) {
|
|
||||||
*error_message = wgettext("Could not find or load game \"")
|
|
||||||
+ narrow_to_wide(worldspec.gameid) + L"\"";
|
|
||||||
errorstream << wide_to_narrow(*error_message) << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (porting::signal_handler_killstatus())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (game_params.game_spec.isValid() &&
|
|
||||||
game_params.game_spec.id != worldspec.gameid) {
|
|
||||||
errorstream << "WARNING: Overriding gamespec from \""
|
|
||||||
<< worldspec.gameid << "\" to \""
|
|
||||||
<< game_params.game_spec.id << "\"" << std::endl;
|
|
||||||
gamespec = game_params.game_spec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gamespec.isValid()) {
|
|
||||||
*error_message = wgettext("Invalid gamespec.");
|
|
||||||
*error_message += L" (world_gameid="
|
|
||||||
+ narrow_to_wide(worldspec.gameid) + L")";
|
|
||||||
errorstream << wide_to_narrow(*error_message) << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientLauncher::main_menu(MainMenuData *menudata)
|
|
||||||
{
|
|
||||||
bool *kill = porting::signal_handler_killstatus();
|
|
||||||
video::IVideoDriver *driver = device->getVideoDriver();
|
|
||||||
|
|
||||||
infostream << "Waiting for other menus" << std::endl;
|
|
||||||
while (device->run() && *kill == false) {
|
|
||||||
if (noMenuActive())
|
|
||||||
break;
|
|
||||||
driver->beginScene(true, true, video::SColor(255, 128, 128, 128));
|
|
||||||
guienv->drawAll();
|
|
||||||
driver->endScene();
|
|
||||||
// On some computers framerate doesn't seem to be automatically limited
|
|
||||||
sleep_ms(25);
|
|
||||||
}
|
|
||||||
infostream << "Waited for other menus" << std::endl;
|
|
||||||
|
|
||||||
// Cursor can be non-visible when coming from the game
|
|
||||||
#ifndef ANDROID
|
|
||||||
device->getCursorControl()->setVisible(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* show main menu */
|
|
||||||
GUIEngine mymenu(device, guiroot, &g_menumgr, smgr, menudata, *kill);
|
|
||||||
|
|
||||||
smgr->clear(); /* leave scene manager in a clean state */
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientLauncher::create_engine_device(int log_level)
|
|
||||||
{
|
|
||||||
static const irr::ELOG_LEVEL irr_log_level[5] = {
|
|
||||||
ELL_NONE,
|
|
||||||
ELL_ERROR,
|
|
||||||
ELL_WARNING,
|
|
||||||
ELL_INFORMATION,
|
|
||||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
|
||||||
ELL_INFORMATION
|
|
||||||
#else
|
|
||||||
ELL_DEBUG
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Resolution selection
|
|
||||||
bool fullscreen = g_settings->getBool("fullscreen");
|
|
||||||
u16 screenW = g_settings->getU16("screenW");
|
|
||||||
u16 screenH = g_settings->getU16("screenH");
|
|
||||||
|
|
||||||
// bpp, fsaa, vsync
|
|
||||||
bool vsync = g_settings->getBool("vsync");
|
|
||||||
u16 bits = g_settings->getU16("fullscreen_bpp");
|
|
||||||
u16 fsaa = g_settings->getU16("fsaa");
|
|
||||||
|
|
||||||
// Determine driver
|
|
||||||
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
|
|
||||||
std::string driverstring = g_settings->get("video_driver");
|
|
||||||
std::vector<video::E_DRIVER_TYPE> drivers
|
|
||||||
= porting::getSupportedVideoDrivers();
|
|
||||||
u32 i;
|
|
||||||
for (i = 0; i != drivers.size(); i++) {
|
|
||||||
if (!strcasecmp(driverstring.c_str(),
|
|
||||||
porting::getVideoDriverName(drivers[i]))) {
|
|
||||||
driverType = drivers[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == drivers.size()) {
|
|
||||||
errorstream << "Invalid video_driver specified; "
|
|
||||||
"defaulting to opengl" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
|
|
||||||
params.DriverType = driverType;
|
|
||||||
params.WindowSize = core::dimension2d<u32>(screenW, screenH);
|
|
||||||
params.Bits = bits;
|
|
||||||
params.AntiAlias = fsaa;
|
|
||||||
params.Fullscreen = fullscreen;
|
|
||||||
params.Stencilbuffer = false;
|
|
||||||
params.Vsync = vsync;
|
|
||||||
params.EventReceiver = receiver;
|
|
||||||
params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
params.PrivateData = porting::app_global;
|
|
||||||
params.OGLES2ShaderPath = std::string(porting::path_user + DIR_DELIM +
|
|
||||||
"media" + DIR_DELIM + "Shaders" + DIR_DELIM).c_str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
device = createDeviceEx(params);
|
|
||||||
|
|
||||||
if (device) {
|
|
||||||
// Map our log level to irrlicht engine one.
|
|
||||||
ILogger* irr_logger = device->getLogger();
|
|
||||||
irr_logger->setLogLevel(irr_log_level[log_level]);
|
|
||||||
|
|
||||||
porting::initIrrlicht(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
return device != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientLauncher::speed_tests()
|
|
||||||
{
|
|
||||||
// volatile to avoid some potential compiler optimisations
|
|
||||||
volatile static s16 temp16;
|
|
||||||
volatile static f32 tempf;
|
|
||||||
static v3f tempv3f1;
|
|
||||||
static v3f tempv3f2;
|
|
||||||
static std::string tempstring;
|
|
||||||
static std::string tempstring2;
|
|
||||||
|
|
||||||
tempv3f1 = v3f();
|
|
||||||
tempv3f2 = v3f();
|
|
||||||
tempstring = std::string();
|
|
||||||
tempstring2 = std::string();
|
|
||||||
|
|
||||||
{
|
|
||||||
infostream << "The following test should take around 20ms." << std::endl;
|
|
||||||
TimeTaker timer("Testing std::string speed");
|
|
||||||
const u32 jj = 10000;
|
|
||||||
for (u32 j = 0; j < jj; j++) {
|
|
||||||
tempstring = "";
|
|
||||||
tempstring2 = "";
|
|
||||||
const u32 ii = 10;
|
|
||||||
for (u32 i = 0; i < ii; i++) {
|
|
||||||
tempstring2 += "asd";
|
|
||||||
}
|
|
||||||
for (u32 i = 0; i < ii+1; i++) {
|
|
||||||
tempstring += "asd";
|
|
||||||
if (tempstring == tempstring2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
infostream << "All of the following tests should take around 100ms each."
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
TimeTaker timer("Testing floating-point conversion speed");
|
|
||||||
tempf = 0.001;
|
|
||||||
for (u32 i = 0; i < 4000000; i++) {
|
|
||||||
temp16 += tempf;
|
|
||||||
tempf += 0.001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
TimeTaker timer("Testing floating-point vector speed");
|
|
||||||
|
|
||||||
tempv3f1 = v3f(1, 2, 3);
|
|
||||||
tempv3f2 = v3f(4, 5, 6);
|
|
||||||
for (u32 i = 0; i < 10000000; i++) {
|
|
||||||
tempf += tempv3f1.dotProduct(tempv3f2);
|
|
||||||
tempv3f2 += v3f(7, 8, 9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
TimeTaker timer("Testing std::map speed");
|
|
||||||
|
|
||||||
std::map<v2s16, f32> map1;
|
|
||||||
tempf = -324;
|
|
||||||
const s16 ii = 300;
|
|
||||||
for (s16 y = 0; y < ii; y++) {
|
|
||||||
for (s16 x = 0; x < ii; x++) {
|
|
||||||
map1[v2s16(x, y)] = tempf;
|
|
||||||
tempf += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (s16 y = ii - 1; y >= 0; y--) {
|
|
||||||
for (s16 x = 0; x < ii; x++) {
|
|
||||||
tempf = map1[v2s16(x, y)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
infostream << "Around 5000/ms should do well here." << std::endl;
|
|
||||||
TimeTaker timer("Testing mutex speed");
|
|
||||||
|
|
||||||
JMutex m;
|
|
||||||
u32 n = 0;
|
|
||||||
u32 i = 0;
|
|
||||||
do {
|
|
||||||
n += 10000;
|
|
||||||
for (; i < n; i++) {
|
|
||||||
m.Lock();
|
|
||||||
m.Unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Do at least 10ms
|
|
||||||
while(timer.getTimerTime() < 10);
|
|
||||||
|
|
||||||
u32 dtime = timer.stop();
|
|
||||||
u32 per_ms = n / dtime;
|
|
||||||
infostream << "Done. " << dtime << "ms, " << per_ms << "/ms" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientLauncher::print_video_modes()
|
|
||||||
{
|
|
||||||
IrrlichtDevice *nulldevice;
|
|
||||||
|
|
||||||
bool vsync = g_settings->getBool("vsync");
|
|
||||||
u16 fsaa = g_settings->getU16("fsaa");
|
|
||||||
MyEventReceiver* receiver = new MyEventReceiver();
|
|
||||||
|
|
||||||
SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
|
|
||||||
params.DriverType = video::EDT_NULL;
|
|
||||||
params.WindowSize = core::dimension2d<u32>(640, 480);
|
|
||||||
params.Bits = 24;
|
|
||||||
params.AntiAlias = fsaa;
|
|
||||||
params.Fullscreen = false;
|
|
||||||
params.Stencilbuffer = false;
|
|
||||||
params.Vsync = vsync;
|
|
||||||
params.EventReceiver = receiver;
|
|
||||||
params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
|
|
||||||
|
|
||||||
nulldevice = createDeviceEx(params);
|
|
||||||
|
|
||||||
if (nulldevice == NULL) {
|
|
||||||
delete receiver;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dstream << _("Available video modes (WxHxD):") << std::endl;
|
|
||||||
|
|
||||||
video::IVideoModeList *videomode_list = nulldevice->getVideoModeList();
|
|
||||||
|
|
||||||
if (videomode_list != NULL) {
|
|
||||||
s32 videomode_count = videomode_list->getVideoModeCount();
|
|
||||||
core::dimension2d<u32> videomode_res;
|
|
||||||
s32 videomode_depth;
|
|
||||||
for (s32 i = 0; i < videomode_count; ++i) {
|
|
||||||
videomode_res = videomode_list->getVideoModeResolution(i);
|
|
||||||
videomode_depth = videomode_list->getVideoModeDepth(i);
|
|
||||||
dstream << videomode_res.Width << "x" << videomode_res.Height
|
|
||||||
<< "x" << videomode_depth << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
dstream << _("Active video mode (WxHxD):") << std::endl;
|
|
||||||
videomode_res = videomode_list->getDesktopResolution();
|
|
||||||
videomode_depth = videomode_list->getDesktopDepth();
|
|
||||||
dstream << videomode_res.Width << "x" << videomode_res.Height
|
|
||||||
<< "x" << videomode_depth << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nulldevice->drop();
|
|
||||||
delete receiver;
|
|
||||||
|
|
||||||
return videomode_list != NULL;
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
/*
|
|
||||||
Minetest
|
|
||||||
Copyright (C) 2010-2013 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 __CLIENT_LAUNCHER_H__
|
|
||||||
#define __CLIENT_LAUNCHER_H__
|
|
||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
|
||||||
#include "client/inputhandler.h"
|
|
||||||
#include "gameparams.h"
|
|
||||||
|
|
||||||
// A small helper class
|
|
||||||
class TimeGetter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual u32 getTime(TimePrecision prec) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A precise irrlicht one
|
|
||||||
class IrrlichtTimeGetter: public TimeGetter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IrrlichtTimeGetter(IrrlichtDevice *device):
|
|
||||||
m_device(device)
|
|
||||||
{}
|
|
||||||
u32 getTime(TimePrecision prec)
|
|
||||||
{
|
|
||||||
if (prec == PRECISION_MILLI) {
|
|
||||||
if (m_device == NULL)
|
|
||||||
return 0;
|
|
||||||
return m_device->getTimer()->getRealTime();
|
|
||||||
} else {
|
|
||||||
return porting::getTime(prec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
IrrlichtDevice *m_device;
|
|
||||||
};
|
|
||||||
// Not so precise one which works without irrlicht
|
|
||||||
class SimpleTimeGetter: public TimeGetter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
u32 getTime(TimePrecision prec)
|
|
||||||
{
|
|
||||||
return porting::getTime(prec);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ClientLauncher
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClientLauncher() :
|
|
||||||
list_video_modes(false),
|
|
||||||
skip_main_menu(false),
|
|
||||||
use_freetype(false),
|
|
||||||
random_input(false),
|
|
||||||
address(""),
|
|
||||||
playername(""),
|
|
||||||
password(""),
|
|
||||||
device(NULL),
|
|
||||||
input(NULL),
|
|
||||||
receiver(NULL),
|
|
||||||
skin(NULL),
|
|
||||||
font(NULL),
|
|
||||||
simple_singleplayer_mode(false),
|
|
||||||
current_playername("inv£lid"),
|
|
||||||
current_password(""),
|
|
||||||
current_address("does-not-exist"),
|
|
||||||
current_port(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~ClientLauncher();
|
|
||||||
|
|
||||||
bool run(GameParams &game_params, const Settings &cmd_args);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init_args(GameParams &game_params, const Settings &cmd_args);
|
|
||||||
bool init_engine(int log_level);
|
|
||||||
|
|
||||||
bool launch_game(std::wstring *error_message, GameParams &game_params,
|
|
||||||
const Settings &cmd_args);
|
|
||||||
|
|
||||||
void main_menu(MainMenuData *menudata);
|
|
||||||
bool create_engine_device(int log_level);
|
|
||||||
|
|
||||||
void speed_tests();
|
|
||||||
bool print_video_modes();
|
|
||||||
|
|
||||||
bool list_video_modes;
|
|
||||||
bool skip_main_menu;
|
|
||||||
bool use_freetype;
|
|
||||||
bool random_input;
|
|
||||||
std::string address;
|
|
||||||
std::string playername;
|
|
||||||
std::string password;
|
|
||||||
IrrlichtDevice *device;
|
|
||||||
InputHandler *input;
|
|
||||||
MyEventReceiver *receiver;
|
|
||||||
gui::IGUISkin *skin;
|
|
||||||
gui::IGUIFont *font;
|
|
||||||
scene::ISceneManager *smgr;
|
|
||||||
SubgameSpec gamespec;
|
|
||||||
WorldSpec worldspec;
|
|
||||||
bool simple_singleplayer_mode;
|
|
||||||
|
|
||||||
// These are set up based on the menu and other things
|
|
||||||
// TODO: Are these required since there's already playername, password, etc
|
|
||||||
std::string current_playername;
|
|
||||||
std::string current_password;
|
|
||||||
std::string current_address;
|
|
||||||
int current_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,428 +0,0 @@
|
||||||
/*
|
|
||||||
Minetest
|
|
||||||
Copyright (C) 2010-2013 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 __INPUT_HANDLER_H__
|
|
||||||
#define __INPUT_HANDLER_H__
|
|
||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
|
||||||
|
|
||||||
class MyEventReceiver : public IEventReceiver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// This is the one method that we have to implement
|
|
||||||
virtual bool OnEvent(const SEvent& event)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
React to nothing here if a menu is active
|
|
||||||
*/
|
|
||||||
if (noMenuActive() == false) {
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
if (m_touchscreengui != 0) {
|
|
||||||
m_touchscreengui->Toggle(false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return g_menumgr.preprocessEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember whether each key is down or up
|
|
||||||
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
|
|
||||||
if (event.KeyInput.PressedDown) {
|
|
||||||
keyIsDown.set(event.KeyInput);
|
|
||||||
keyWasDown.set(event.KeyInput);
|
|
||||||
} else {
|
|
||||||
keyIsDown.unset(event.KeyInput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
// case of touchscreengui we have to handle different events
|
|
||||||
if ((m_touchscreengui != 0) &&
|
|
||||||
(event.EventType == irr::EET_TOUCH_INPUT_EVENT)) {
|
|
||||||
m_touchscreengui->translateEvent(event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// handle mouse events
|
|
||||||
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
|
|
||||||
if (noMenuActive() == false) {
|
|
||||||
left_active = false;
|
|
||||||
middle_active = false;
|
|
||||||
right_active = false;
|
|
||||||
} else {
|
|
||||||
left_active = event.MouseInput.isLeftPressed();
|
|
||||||
middle_active = event.MouseInput.isMiddlePressed();
|
|
||||||
right_active = event.MouseInput.isRightPressed();
|
|
||||||
|
|
||||||
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
|
|
||||||
leftclicked = true;
|
|
||||||
}
|
|
||||||
if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
|
|
||||||
rightclicked = true;
|
|
||||||
}
|
|
||||||
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
|
|
||||||
leftreleased = true;
|
|
||||||
}
|
|
||||||
if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
|
|
||||||
rightreleased = true;
|
|
||||||
}
|
|
||||||
if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
|
|
||||||
mouse_wheel += event.MouseInput.Wheel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
|
|
||||||
dstream << std::string("Irrlicht log: ") + std::string(event.LogEvent.Text)
|
|
||||||
<< std::endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/* always return false in order to continue processing events */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsKeyDown(const KeyPress &keyCode) const
|
|
||||||
{
|
|
||||||
return keyIsDown[keyCode];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks whether a key was down and resets the state
|
|
||||||
bool WasKeyDown(const KeyPress &keyCode)
|
|
||||||
{
|
|
||||||
bool b = keyWasDown[keyCode];
|
|
||||||
if (b)
|
|
||||||
keyWasDown.unset(keyCode);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 getMouseWheel()
|
|
||||||
{
|
|
||||||
s32 a = mouse_wheel;
|
|
||||||
mouse_wheel = 0;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearInput()
|
|
||||||
{
|
|
||||||
keyIsDown.clear();
|
|
||||||
keyWasDown.clear();
|
|
||||||
|
|
||||||
leftclicked = false;
|
|
||||||
rightclicked = false;
|
|
||||||
leftreleased = false;
|
|
||||||
rightreleased = false;
|
|
||||||
|
|
||||||
left_active = false;
|
|
||||||
middle_active = false;
|
|
||||||
right_active = false;
|
|
||||||
|
|
||||||
mouse_wheel = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyEventReceiver()
|
|
||||||
{
|
|
||||||
clearInput();
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
m_touchscreengui = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool leftclicked;
|
|
||||||
bool rightclicked;
|
|
||||||
bool leftreleased;
|
|
||||||
bool rightreleased;
|
|
||||||
|
|
||||||
bool left_active;
|
|
||||||
bool middle_active;
|
|
||||||
bool right_active;
|
|
||||||
|
|
||||||
s32 mouse_wheel;
|
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
|
||||||
TouchScreenGUI* m_touchscreengui;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The current state of keys
|
|
||||||
KeyList keyIsDown;
|
|
||||||
// Whether a key has been pressed or not
|
|
||||||
KeyList keyWasDown;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Separated input handler
|
|
||||||
*/
|
|
||||||
|
|
||||||
class RealInputHandler : public InputHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver):
|
|
||||||
m_device(device),
|
|
||||||
m_receiver(receiver),
|
|
||||||
m_mousepos(0,0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
virtual bool isKeyDown(const KeyPress &keyCode)
|
|
||||||
{
|
|
||||||
return m_receiver->IsKeyDown(keyCode);
|
|
||||||
}
|
|
||||||
virtual bool wasKeyDown(const KeyPress &keyCode)
|
|
||||||
{
|
|
||||||
return m_receiver->WasKeyDown(keyCode);
|
|
||||||
}
|
|
||||||
virtual v2s32 getMousePos()
|
|
||||||
{
|
|
||||||
if (m_device->getCursorControl()) {
|
|
||||||
return m_device->getCursorControl()->getPosition();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return m_mousepos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual void setMousePos(s32 x, s32 y)
|
|
||||||
{
|
|
||||||
if (m_device->getCursorControl()) {
|
|
||||||
m_device->getCursorControl()->setPosition(x, y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_mousepos = v2s32(x,y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftState()
|
|
||||||
{
|
|
||||||
return m_receiver->left_active;
|
|
||||||
}
|
|
||||||
virtual bool getRightState()
|
|
||||||
{
|
|
||||||
return m_receiver->right_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftClicked()
|
|
||||||
{
|
|
||||||
return m_receiver->leftclicked;
|
|
||||||
}
|
|
||||||
virtual bool getRightClicked()
|
|
||||||
{
|
|
||||||
return m_receiver->rightclicked;
|
|
||||||
}
|
|
||||||
virtual void resetLeftClicked()
|
|
||||||
{
|
|
||||||
m_receiver->leftclicked = false;
|
|
||||||
}
|
|
||||||
virtual void resetRightClicked()
|
|
||||||
{
|
|
||||||
m_receiver->rightclicked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftReleased()
|
|
||||||
{
|
|
||||||
return m_receiver->leftreleased;
|
|
||||||
}
|
|
||||||
virtual bool getRightReleased()
|
|
||||||
{
|
|
||||||
return m_receiver->rightreleased;
|
|
||||||
}
|
|
||||||
virtual void resetLeftReleased()
|
|
||||||
{
|
|
||||||
m_receiver->leftreleased = false;
|
|
||||||
}
|
|
||||||
virtual void resetRightReleased()
|
|
||||||
{
|
|
||||||
m_receiver->rightreleased = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual s32 getMouseWheel()
|
|
||||||
{
|
|
||||||
return m_receiver->getMouseWheel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
m_receiver->clearInput();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
IrrlichtDevice *m_device;
|
|
||||||
MyEventReceiver *m_receiver;
|
|
||||||
v2s32 m_mousepos;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RandomInputHandler : public InputHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RandomInputHandler()
|
|
||||||
{
|
|
||||||
leftdown = false;
|
|
||||||
rightdown = false;
|
|
||||||
leftclicked = false;
|
|
||||||
rightclicked = false;
|
|
||||||
leftreleased = false;
|
|
||||||
rightreleased = false;
|
|
||||||
keydown.clear();
|
|
||||||
}
|
|
||||||
virtual bool isKeyDown(const KeyPress &keyCode)
|
|
||||||
{
|
|
||||||
return keydown[keyCode];
|
|
||||||
}
|
|
||||||
virtual bool wasKeyDown(const KeyPress &keyCode)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual v2s32 getMousePos()
|
|
||||||
{
|
|
||||||
return mousepos;
|
|
||||||
}
|
|
||||||
virtual void setMousePos(s32 x, s32 y)
|
|
||||||
{
|
|
||||||
mousepos = v2s32(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftState()
|
|
||||||
{
|
|
||||||
return leftdown;
|
|
||||||
}
|
|
||||||
virtual bool getRightState()
|
|
||||||
{
|
|
||||||
return rightdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftClicked()
|
|
||||||
{
|
|
||||||
return leftclicked;
|
|
||||||
}
|
|
||||||
virtual bool getRightClicked()
|
|
||||||
{
|
|
||||||
return rightclicked;
|
|
||||||
}
|
|
||||||
virtual void resetLeftClicked()
|
|
||||||
{
|
|
||||||
leftclicked = false;
|
|
||||||
}
|
|
||||||
virtual void resetRightClicked()
|
|
||||||
{
|
|
||||||
rightclicked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool getLeftReleased()
|
|
||||||
{
|
|
||||||
return leftreleased;
|
|
||||||
}
|
|
||||||
virtual bool getRightReleased()
|
|
||||||
{
|
|
||||||
return rightreleased;
|
|
||||||
}
|
|
||||||
virtual void resetLeftReleased()
|
|
||||||
{
|
|
||||||
leftreleased = false;
|
|
||||||
}
|
|
||||||
virtual void resetRightReleased()
|
|
||||||
{
|
|
||||||
rightreleased = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual s32 getMouseWheel()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void step(float dtime)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 40);
|
|
||||||
keydown.toggle(getKeySetting("keymap_jump"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 40);
|
|
||||||
keydown.toggle(getKeySetting("keymap_special1"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 40);
|
|
||||||
keydown.toggle(getKeySetting("keymap_forward"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 40);
|
|
||||||
keydown.toggle(getKeySetting("keymap_left"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 20);
|
|
||||||
mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 30);
|
|
||||||
leftdown = !leftdown;
|
|
||||||
if (leftdown)
|
|
||||||
leftclicked = true;
|
|
||||||
if (!leftdown)
|
|
||||||
leftreleased = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
static float counter1 = 0;
|
|
||||||
counter1 -= dtime;
|
|
||||||
if (counter1 < 0.0) {
|
|
||||||
counter1 = 0.1 * Rand(1, 15);
|
|
||||||
rightdown = !rightdown;
|
|
||||||
if (rightdown)
|
|
||||||
rightclicked = true;
|
|
||||||
if (!rightdown)
|
|
||||||
rightreleased = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mousepos += mousespeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 Rand(s32 min, s32 max)
|
|
||||||
{
|
|
||||||
return (myrand()%(max-min+1))+min;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
KeyList keydown;
|
|
||||||
v2s32 mousepos;
|
|
||||||
v2s32 mousespeed;
|
|
||||||
bool leftdown;
|
|
||||||
bool rightdown;
|
|
||||||
bool leftclicked;
|
|
||||||
bool rightclicked;
|
|
||||||
bool leftreleased;
|
|
||||||
bool rightreleased;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "network/connection.h"
|
#include "connection.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "emerge.h"
|
#include "emerge.h"
|
||||||
|
@ -59,7 +59,7 @@ void RemoteClient::ResendBlockIfOnWire(v3s16 p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteClient::GetNextBlocks (
|
void RemoteClient::GetNextBlocks(
|
||||||
ServerEnvironment *env,
|
ServerEnvironment *env,
|
||||||
EmergeManager * emerge,
|
EmergeManager * emerge,
|
||||||
float dtime,
|
float dtime,
|
||||||
|
@ -182,15 +182,18 @@ void RemoteClient::GetNextBlocks (
|
||||||
//bool queue_is_full = false;
|
//bool queue_is_full = false;
|
||||||
|
|
||||||
s16 d;
|
s16 d;
|
||||||
for(d = d_start; d <= d_max; d++) {
|
for(d = d_start; d <= d_max; d++)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
Get the border/face dot coordinates of a "d-radiused"
|
Get the border/face dot coordinates of a "d-radiused"
|
||||||
box
|
box
|
||||||
*/
|
*/
|
||||||
std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
|
std::list<v3s16> list;
|
||||||
|
getFacePositions(list, d);
|
||||||
|
|
||||||
std::vector<v3s16>::iterator li;
|
std::list<v3s16>::iterator li;
|
||||||
for(li = list.begin(); li != list.end(); ++li) {
|
for(li=list.begin(); li!=list.end(); ++li)
|
||||||
|
{
|
||||||
v3s16 p = *li + center;
|
v3s16 p = *li + center;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -560,9 +563,9 @@ ClientInterface::~ClientInterface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
|
std::list<u16> ClientInterface::getClientIDs(ClientState min_state)
|
||||||
{
|
{
|
||||||
std::vector<u16> reply;
|
std::list<u16> reply;
|
||||||
JMutexAutoLock clientslock(m_clients_mutex);
|
JMutexAutoLock clientslock(m_clients_mutex);
|
||||||
|
|
||||||
for(std::map<u16, RemoteClient*>::iterator
|
for(std::map<u16, RemoteClient*>::iterator
|
||||||
|
@ -596,22 +599,20 @@ void ClientInterface::UpdatePlayerList()
|
||||||
{
|
{
|
||||||
if (m_env != NULL)
|
if (m_env != NULL)
|
||||||
{
|
{
|
||||||
std::vector<u16> clients = getClientIDs();
|
std::list<u16> clients = getClientIDs();
|
||||||
m_clients_names.clear();
|
m_clients_names.clear();
|
||||||
|
|
||||||
|
|
||||||
if(!clients.empty())
|
if(!clients.empty())
|
||||||
infostream<<"Players:"<<std::endl;
|
infostream<<"Players:"<<std::endl;
|
||||||
|
for(std::list<u16>::iterator
|
||||||
for(std::vector<u16>::iterator
|
|
||||||
i = clients.begin();
|
i = clients.begin();
|
||||||
i != clients.end(); ++i) {
|
i != clients.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = m_env->getPlayer(*i);
|
Player *player = m_env->getPlayer(*i);
|
||||||
|
if(player==NULL)
|
||||||
if (player == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
infostream<<"* "<<player->getName()<<"\t";
|
||||||
infostream << "* " << player->getName() << "\t";
|
|
||||||
|
|
||||||
{
|
{
|
||||||
JMutexAutoLock clientslock(m_clients_mutex);
|
JMutexAutoLock clientslock(m_clients_mutex);
|
||||||
|
@ -619,36 +620,32 @@ void ClientInterface::UpdatePlayerList()
|
||||||
if(client != NULL)
|
if(client != NULL)
|
||||||
client->PrintInfo(infostream);
|
client->PrintInfo(infostream);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clients_names.push_back(player->getName());
|
m_clients_names.push_back(player->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientInterface::send(u16 peer_id, u8 channelnum,
|
void ClientInterface::send(u16 peer_id,u8 channelnum,
|
||||||
NetworkPacket* pkt, bool reliable, bool deletepkt)
|
SharedBuffer<u8> data, bool reliable)
|
||||||
{
|
{
|
||||||
m_con->Send(peer_id, channelnum, pkt, reliable);
|
m_con->Send(peer_id, channelnum, data, reliable);
|
||||||
|
|
||||||
if (deletepkt)
|
|
||||||
delete pkt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientInterface::sendToAll(u16 channelnum,
|
void ClientInterface::sendToAll(u16 channelnum,
|
||||||
NetworkPacket* pkt, bool reliable)
|
SharedBuffer<u8> data, bool reliable)
|
||||||
{
|
{
|
||||||
JMutexAutoLock clientslock(m_clients_mutex);
|
JMutexAutoLock clientslock(m_clients_mutex);
|
||||||
for(std::map<u16, RemoteClient*>::iterator
|
for(std::map<u16, RemoteClient*>::iterator
|
||||||
i = m_clients.begin();
|
i = m_clients.begin();
|
||||||
i != m_clients.end(); ++i) {
|
i != m_clients.end(); ++i)
|
||||||
|
{
|
||||||
RemoteClient *client = i->second;
|
RemoteClient *client = i->second;
|
||||||
|
|
||||||
if (client->net_proto_version != 0) {
|
if (client->net_proto_version != 0)
|
||||||
m_con->Send(client->peer_id, channelnum, pkt, reliable);
|
{
|
||||||
|
m_con->Send(client->peer_id, channelnum, data, reliable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pkt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
|
RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
|
||||||
|
|
|
@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "serialization.h" // for SER_FMT_VER_INVALID
|
#include "serialization.h" // for SER_FMT_VER_INVALID
|
||||||
#include "jthread/jmutex.h"
|
#include "jthread/jmutex.h"
|
||||||
#include "network/networkpacket.h"
|
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -388,16 +387,16 @@ public:
|
||||||
void step(float dtime);
|
void step(float dtime);
|
||||||
|
|
||||||
/* get list of active client id's */
|
/* get list of active client id's */
|
||||||
std::vector<u16> getClientIDs(ClientState min_state=CS_Active);
|
std::list<u16> getClientIDs(ClientState min_state=CS_Active);
|
||||||
|
|
||||||
/* get list of client player names */
|
/* get list of client player names */
|
||||||
std::vector<std::string> getPlayerNames();
|
std::vector<std::string> getPlayerNames();
|
||||||
|
|
||||||
/* send message to client */
|
/* send message to client */
|
||||||
void send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable, bool deletepkt=true);
|
void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
|
|
||||||
/* send to all clients */
|
/* send to all clients */
|
||||||
void sendToAll(u16 channelnum, NetworkPacket* pkt, bool reliable);
|
void sendToAll(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
|
|
||||||
/* delete a client */
|
/* delete a client */
|
||||||
void DeleteClient(u16 peer_id);
|
void DeleteClient(u16 peer_id);
|
||||||
|
@ -458,7 +457,7 @@ private:
|
||||||
JMutex m_env_mutex;
|
JMutex m_env_mutex;
|
||||||
|
|
||||||
float m_print_info_timer;
|
float m_print_info_timer;
|
||||||
|
|
||||||
static const char *statenames[];
|
static const char *statenames[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -161,9 +161,9 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
|
||||||
else
|
else
|
||||||
is_transparent = (f.solidness != 2);
|
is_transparent = (f.solidness != 2);
|
||||||
if(!is_transparent){
|
if(!is_transparent){
|
||||||
if(count == needed_count)
|
|
||||||
return true;
|
|
||||||
count++;
|
count++;
|
||||||
|
if(count >= needed_count)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
step *= stepfac;
|
step *= stepfac;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapBlockVect sectorblocks;
|
std::list< MapBlock * > sectorblocks;
|
||||||
sector->getBlocks(sectorblocks);
|
sector->getBlocks(sectorblocks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -256,8 +256,8 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
||||||
|
|
||||||
u32 sector_blocks_drawn = 0;
|
u32 sector_blocks_drawn = 0;
|
||||||
|
|
||||||
for(MapBlockVect::iterator i = sectorblocks.begin();
|
std::list< MapBlock * >::iterator i;
|
||||||
i != sectorblocks.end(); i++)
|
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
||||||
{
|
{
|
||||||
MapBlock *block = *i;
|
MapBlock *block = *i;
|
||||||
|
|
||||||
|
@ -391,12 +391,12 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
||||||
struct MeshBufList
|
struct MeshBufList
|
||||||
{
|
{
|
||||||
video::SMaterial m;
|
video::SMaterial m;
|
||||||
std::vector<scene::IMeshBuffer*> bufs;
|
std::list<scene::IMeshBuffer*> bufs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshBufListList
|
struct MeshBufListList
|
||||||
{
|
{
|
||||||
std::vector<MeshBufList> lists;
|
std::list<MeshBufList> lists;
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
|
@ -405,7 +405,7 @@ struct MeshBufListList
|
||||||
|
|
||||||
void add(scene::IMeshBuffer *buf)
|
void add(scene::IMeshBuffer *buf)
|
||||||
{
|
{
|
||||||
for(std::vector<MeshBufList>::iterator i = lists.begin();
|
for(std::list<MeshBufList>::iterator i = lists.begin();
|
||||||
i != lists.end(); ++i){
|
i != lists.end(); ++i){
|
||||||
MeshBufList &l = *i;
|
MeshBufList &l = *i;
|
||||||
video::SMaterial &m = buf->getMaterial();
|
video::SMaterial &m = buf->getMaterial();
|
||||||
|
@ -595,20 +595,25 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MeshBufList> &lists = drawbufs.lists;
|
std::list<MeshBufList> &lists = drawbufs.lists;
|
||||||
|
|
||||||
int timecheck_counter = 0;
|
int timecheck_counter = 0;
|
||||||
for(std::vector<MeshBufList>::iterator i = lists.begin();
|
for(std::list<MeshBufList>::iterator i = lists.begin();
|
||||||
i != lists.end(); ++i) {
|
i != lists.end(); ++i)
|
||||||
timecheck_counter++;
|
{
|
||||||
if(timecheck_counter > 50) {
|
{
|
||||||
timecheck_counter = 0;
|
timecheck_counter++;
|
||||||
int time2 = time(0);
|
if(timecheck_counter > 50)
|
||||||
if(time2 > time1 + 4) {
|
{
|
||||||
infostream << "ClientMap::renderMap(): "
|
timecheck_counter = 0;
|
||||||
"Rendering takes ages, returning."
|
int time2 = time(0);
|
||||||
<< std::endl;
|
if(time2 > time1 + 4)
|
||||||
return;
|
{
|
||||||
|
infostream<<"ClientMap::renderMap(): "
|
||||||
|
"Rendering takes ages, returning."
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,14 +621,60 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
|
|
||||||
driver->setMaterial(list.m);
|
driver->setMaterial(list.m);
|
||||||
|
|
||||||
for(std::vector<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
|
for(std::list<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
|
||||||
j != list.bufs.end(); ++j) {
|
j != list.bufs.end(); ++j)
|
||||||
|
{
|
||||||
scene::IMeshBuffer *buf = *j;
|
scene::IMeshBuffer *buf = *j;
|
||||||
driver->drawMeshBuffer(buf);
|
driver->drawMeshBuffer(buf);
|
||||||
vertex_count += buf->getVertexCount();
|
vertex_count += buf->getVertexCount();
|
||||||
meshbuffer_count++;
|
meshbuffer_count++;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
Draw the faces of the block
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
//JMutexAutoLock lock(block->mesh_mutex);
|
||||||
|
|
||||||
|
MapBlockMesh *mapBlockMesh = block->mesh;
|
||||||
|
assert(mapBlockMesh);
|
||||||
|
|
||||||
|
scene::SMesh *mesh = mapBlockMesh->getMesh();
|
||||||
|
assert(mesh);
|
||||||
|
|
||||||
|
u32 c = mesh->getMeshBufferCount();
|
||||||
|
bool stuff_actually_drawn = false;
|
||||||
|
for(u32 i=0; i<c; i++)
|
||||||
|
{
|
||||||
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
|
||||||
|
const video::SMaterial& material = buf->getMaterial();
|
||||||
|
video::IMaterialRenderer* rnd =
|
||||||
|
driver->getMaterialRenderer(material.MaterialType);
|
||||||
|
bool transparent = (rnd && rnd->isTransparent());
|
||||||
|
// Render transparent on transparent pass and likewise.
|
||||||
|
if(transparent == is_transparent_pass)
|
||||||
|
{
|
||||||
|
if(buf->getVertexCount() == 0)
|
||||||
|
errorstream<<"Block ["<<analyze_block(block)
|
||||||
|
<<"] contains an empty meshbuf"<<std::endl;
|
||||||
|
/*
|
||||||
|
This *shouldn't* hurt too much because Irrlicht
|
||||||
|
doesn't change opengl textures if the old
|
||||||
|
material has the same texture.
|
||||||
|
*/
|
||||||
|
driver->setMaterial(buf->getMaterial());
|
||||||
|
driver->drawMeshBuffer(buf);
|
||||||
|
vertex_count += buf->getVertexCount();
|
||||||
|
meshbuffer_count++;
|
||||||
|
stuff_actually_drawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(stuff_actually_drawn)
|
||||||
|
blocks_had_pass_meshbuf++;
|
||||||
|
else
|
||||||
|
blocks_without_stuff++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} // ScopeProfiler
|
} // ScopeProfiler
|
||||||
|
|
||||||
|
|
|
@ -18,20 +18,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clientmedia.h"
|
#include "clientmedia.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
#include "util/string.h"
|
||||||
#include "httpfetch.h"
|
#include "httpfetch.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "clientserver.h"
|
||||||
#include "filecache.h"
|
#include "filecache.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
|
#include "hex.h"
|
||||||
|
#include "sha1.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "network/networkprotocol.h"
|
|
||||||
#include "util/hex.h"
|
|
||||||
#include "util/serialize.h"
|
|
||||||
#include "util/sha1.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
static std::string getMediaCacheDir()
|
static std::string getMediaCacheDir()
|
||||||
{
|
{
|
||||||
|
@ -488,7 +488,7 @@ void ClientMediaDownloader::startConventionalTransfers(Client *client)
|
||||||
if (m_uncached_received_count != m_uncached_count) {
|
if (m_uncached_received_count != m_uncached_count) {
|
||||||
// Some media files have not been received yet, use the
|
// Some media files have not been received yet, use the
|
||||||
// conventional slow method (minetest protocol) to get them
|
// conventional slow method (minetest protocol) to get them
|
||||||
std::vector<std::string> file_requests;
|
std::list<std::string> file_requests;
|
||||||
for (std::map<std::string, FileStatus*>::iterator
|
for (std::map<std::string, FileStatus*>::iterator
|
||||||
it = m_files.begin();
|
it = m_files.begin();
|
||||||
it != m_files.end(); ++it) {
|
it != m_files.end(); ++it) {
|
||||||
|
|
|
@ -39,13 +39,14 @@ ClientActiveObject::~ClientActiveObject()
|
||||||
removeFromScene(true);
|
removeFromScene(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientActiveObject* ClientActiveObject::create(ActiveObjectType type,
|
ClientActiveObject* ClientActiveObject::create(u8 type, IGameDef *gamedef,
|
||||||
IGameDef *gamedef, ClientEnvironment *env)
|
ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
// Find factory function
|
// Find factory function
|
||||||
std::map<u16, Factory>::iterator n;
|
std::map<u16, Factory>::iterator n;
|
||||||
n = m_types.find(type);
|
n = m_types.find(type);
|
||||||
if(n == m_types.end()) {
|
if(n == m_types.end())
|
||||||
|
{
|
||||||
// If factory is not found, just return.
|
// If factory is not found, just return.
|
||||||
dstream<<"WARNING: ClientActiveObject: No factory for type="
|
dstream<<"WARNING: ClientActiveObject: No factory for type="
|
||||||
<<(int)type<<std::endl;
|
<<(int)type<<std::endl;
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
virtual void initialize(const std::string &data){}
|
virtual void initialize(const std::string &data){}
|
||||||
|
|
||||||
// Create a certain type of ClientActiveObject
|
// Create a certain type of ClientActiveObject
|
||||||
static ClientActiveObject* create(ActiveObjectType type, IGameDef *gamedef,
|
static ClientActiveObject* create(u8 type, IGameDef *gamedef,
|
||||||
ClientEnvironment *env);
|
ClientEnvironment *env);
|
||||||
|
|
||||||
// If returns true, punch will not be sent to the server
|
// If returns true, punch will not be sent to the server
|
||||||
|
|
|
@ -17,8 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NETWORKPROTOCOL_HEADER
|
#ifndef CLIENTSERVER_HEADER
|
||||||
#define NETWORKPROTOCOL_HEADER
|
#define CLIENTSERVER_HEADER
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -556,8 +556,6 @@ enum ToClientCommand
|
||||||
v3f1000 first
|
v3f1000 first
|
||||||
v3f1000 third
|
v3f1000 third
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOCLIENT_NUM_MSG_TYPES = 0x53,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ToServerCommand
|
enum ToServerCommand
|
||||||
|
@ -661,7 +659,7 @@ enum ToServerCommand
|
||||||
|
|
||||||
TOSERVER_INVENTORY_ACTION = 0x31,
|
TOSERVER_INVENTORY_ACTION = 0x31,
|
||||||
/*
|
/*
|
||||||
See InventoryAction in inventorymanager.h
|
See InventoryAction in inventory.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_CHAT_MESSAGE = 0x32,
|
TOSERVER_CHAT_MESSAGE = 0x32,
|
||||||
|
@ -797,8 +795,7 @@ enum ToServerCommand
|
||||||
u16 len
|
u16 len
|
||||||
u8[len] full_version_string
|
u8[len] full_version_string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_NUM_MSG_TYPES = 0x44,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -300,14 +300,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
/* add object boxes to cboxes */
|
/* add object boxes to cboxes */
|
||||||
|
|
||||||
|
|
||||||
std::vector<ActiveObject*> objects;
|
std::list<ActiveObject*> objects;
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
|
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
|
||||||
if (c_env != 0) {
|
if (c_env != 0)
|
||||||
|
{
|
||||||
f32 distance = speed_f.getLength();
|
f32 distance = speed_f.getLength();
|
||||||
std::vector<DistanceSortedActiveObject> clientobjects;
|
std::vector<DistanceSortedActiveObject> clientobjects;
|
||||||
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
|
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
|
||||||
for (size_t i=0; i < clientobjects.size(); i++) {
|
for (size_t i=0; i < clientobjects.size(); i++)
|
||||||
|
{
|
||||||
if ((self == 0) || (self != clientobjects[i].obj)) {
|
if ((self == 0) || (self != clientobjects[i].obj)) {
|
||||||
objects.push_back((ActiveObject*)clientobjects[i].obj);
|
objects.push_back((ActiveObject*)clientobjects[i].obj);
|
||||||
}
|
}
|
||||||
|
@ -317,10 +319,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
|
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
|
||||||
if (s_env != 0) {
|
if (s_env != 0)
|
||||||
|
{
|
||||||
f32 distance = speed_f.getLength();
|
f32 distance = speed_f.getLength();
|
||||||
std::set<u16> s_objects = s_env->getObjectsInsideRadius(pos_f,distance * 1.5);
|
std::set<u16> s_objects = s_env->getObjectsInsideRadius(pos_f,distance * 1.5);
|
||||||
for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++) {
|
for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++)
|
||||||
|
{
|
||||||
ServerActiveObject *current = s_env->getActiveObject(*iter);
|
ServerActiveObject *current = s_env->getActiveObject(*iter);
|
||||||
if ((self == 0) || (self != current)) {
|
if ((self == 0) || (self != current)) {
|
||||||
objects.push_back((ActiveObject*)current);
|
objects.push_back((ActiveObject*)current);
|
||||||
|
@ -329,14 +333,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::vector<ActiveObject*>::const_iterator iter = objects.begin();
|
for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter)
|
||||||
iter != objects.end(); ++iter) {
|
{
|
||||||
ActiveObject *object = *iter;
|
ActiveObject *object = *iter;
|
||||||
|
|
||||||
if (object != NULL) {
|
if (object != NULL)
|
||||||
|
{
|
||||||
aabb3f object_collisionbox;
|
aabb3f object_collisionbox;
|
||||||
if (object->getCollisionBox(&object_collisionbox) &&
|
if (object->getCollisionBox(&object_collisionbox) &&
|
||||||
object->collideWithObjects()) {
|
object->collideWithObjects())
|
||||||
|
{
|
||||||
cboxes.push_back(object_collisionbox);
|
cboxes.push_back(object_collisionbox);
|
||||||
is_unloaded.push_back(false);
|
is_unloaded.push_back(false);
|
||||||
is_step_up.push_back(false);
|
is_step_up.push_back(false);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "network/networkpacket.h"
|
|
||||||
#include "util/pointer.h"
|
#include "util/pointer.h"
|
||||||
#include "util/container.h"
|
#include "util/container.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
@ -131,14 +130,14 @@ inline bool seqnum_higher(u16 totest, u16 base)
|
||||||
{
|
{
|
||||||
if (totest > base)
|
if (totest > base)
|
||||||
{
|
{
|
||||||
if ((totest - base) > (SEQNUM_MAX/2))
|
if((totest - base) > (SEQNUM_MAX/2))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((base - totest) > (SEQNUM_MAX/2))
|
if((base - totest) > (SEQNUM_MAX/2))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -363,9 +362,9 @@ public:
|
||||||
packet is constructed. If not, returns one of length 0.
|
packet is constructed. If not, returns one of length 0.
|
||||||
*/
|
*/
|
||||||
SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
|
SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
|
||||||
|
|
||||||
void removeUnreliableTimedOuts(float dtime, float timeout);
|
void removeUnreliableTimedOuts(float dtime, float timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Key is seqnum
|
// Key is seqnum
|
||||||
std::map<u16, IncomingSplitPacket*> m_buf;
|
std::map<u16, IncomingSplitPacket*> m_buf;
|
||||||
|
@ -496,7 +495,7 @@ public:
|
||||||
|
|
||||||
u16 readNextSplitSeqNum();
|
u16 readNextSplitSeqNum();
|
||||||
void setNextSplitSeqNum(u16 seqnum);
|
void setNextSplitSeqNum(u16 seqnum);
|
||||||
|
|
||||||
// This is for buffering the incoming packets that are coming in
|
// This is for buffering the incoming packets that are coming in
|
||||||
// the wrong order
|
// the wrong order
|
||||||
ReliablePacketBuffer incoming_reliables;
|
ReliablePacketBuffer incoming_reliables;
|
||||||
|
@ -505,10 +504,10 @@ public:
|
||||||
ReliablePacketBuffer outgoing_reliables_sent;
|
ReliablePacketBuffer outgoing_reliables_sent;
|
||||||
|
|
||||||
//queued reliable packets
|
//queued reliable packets
|
||||||
std::queue<BufferedPacket> queued_reliables;
|
Queue<BufferedPacket> queued_reliables;
|
||||||
|
|
||||||
//queue commands prior splitting to packets
|
//queue commands prior splitting to packets
|
||||||
std::queue<ConnectionCommand> queued_commands;
|
Queue<ConnectionCommand> queued_commands;
|
||||||
|
|
||||||
IncomingSplitBuffer incoming_splits;
|
IncomingSplitBuffer incoming_splits;
|
||||||
|
|
||||||
|
@ -874,7 +873,7 @@ struct ConnectionEvent
|
||||||
|
|
||||||
std::string describe()
|
std::string describe()
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch(type){
|
||||||
case CONNEVENT_NONE:
|
case CONNEVENT_NONE:
|
||||||
return "CONNEVENT_NONE";
|
return "CONNEVENT_NONE";
|
||||||
case CONNEVENT_DATA_RECEIVED:
|
case CONNEVENT_DATA_RECEIVED:
|
||||||
|
@ -888,7 +887,7 @@ struct ConnectionEvent
|
||||||
}
|
}
|
||||||
return "Invalid ConnectionEvent";
|
return "Invalid ConnectionEvent";
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
|
void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
|
||||||
{
|
{
|
||||||
type = CONNEVENT_DATA_RECEIVED;
|
type = CONNEVENT_DATA_RECEIVED;
|
||||||
|
@ -964,7 +963,7 @@ private:
|
||||||
Connection* m_connection;
|
Connection* m_connection;
|
||||||
unsigned int m_max_packet_size;
|
unsigned int m_max_packet_size;
|
||||||
float m_timeout;
|
float m_timeout;
|
||||||
std::queue<OutgoingPacket> m_outgoing_queue;
|
Queue<OutgoingPacket> m_outgoing_queue;
|
||||||
JSemaphore m_send_sleep_semaphore;
|
JSemaphore m_send_sleep_semaphore;
|
||||||
|
|
||||||
unsigned int m_iteration_packets_avaialble;
|
unsigned int m_iteration_packets_avaialble;
|
||||||
|
@ -1026,15 +1025,16 @@ public:
|
||||||
ConnectionEvent getEvent();
|
ConnectionEvent getEvent();
|
||||||
ConnectionEvent waitEvent(u32 timeout_ms);
|
ConnectionEvent waitEvent(u32 timeout_ms);
|
||||||
void putCommand(ConnectionCommand &c);
|
void putCommand(ConnectionCommand &c);
|
||||||
|
|
||||||
void SetTimeoutMs(int timeout) { m_bc_receive_timeout = timeout; }
|
void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
|
||||||
void Serve(Address bind_addr);
|
void Serve(Address bind_addr);
|
||||||
void Connect(Address address);
|
void Connect(Address address);
|
||||||
bool Connected();
|
bool Connected();
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
|
u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
|
||||||
void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
|
void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
u16 GetPeerID() { return m_peer_id; }
|
void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||||
|
u16 GetPeerID(){ return m_peer_id; }
|
||||||
Address GetPeerAddress(u16 peer_id);
|
Address GetPeerAddress(u16 peer_id);
|
||||||
float getPeerStat(u16 peer_id, rtt_stat_type type);
|
float getPeerStat(u16 peer_id, rtt_stat_type type);
|
||||||
float getLocalStat(rate_stat_type type);
|
float getLocalStat(rate_stat_type type);
|
||||||
|
@ -1051,14 +1051,14 @@ protected:
|
||||||
UDPPeer* createServerPeer(Address& sender);
|
UDPPeer* createServerPeer(Address& sender);
|
||||||
bool deletePeer(u16 peer_id, bool timeout);
|
bool deletePeer(u16 peer_id, bool timeout);
|
||||||
|
|
||||||
void SetPeerID(u16 id) { m_peer_id = id; }
|
void SetPeerID(u16 id){ m_peer_id = id; }
|
||||||
|
|
||||||
void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
|
void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
|
||||||
|
|
||||||
void PrintInfo(std::ostream &out);
|
void PrintInfo(std::ostream &out);
|
||||||
void PrintInfo();
|
void PrintInfo();
|
||||||
|
|
||||||
std::list<u16> getPeerIDs() { return m_peer_ids; }
|
std::list<u16> getPeerIDs();
|
||||||
|
|
||||||
UDPSocket m_udpSocket;
|
UDPSocket m_udpSocket;
|
||||||
MutexedQueue<ConnectionCommand> m_command_queue;
|
MutexedQueue<ConnectionCommand> m_command_queue;
|
||||||
|
@ -1074,9 +1074,8 @@ private:
|
||||||
|
|
||||||
u16 m_peer_id;
|
u16 m_peer_id;
|
||||||
u32 m_protocol_id;
|
u32 m_protocol_id;
|
||||||
|
|
||||||
std::map<u16, Peer*> m_peers;
|
std::map<u16, Peer*> m_peers;
|
||||||
std::list<u16> m_peer_ids;
|
|
||||||
JMutex m_peers_mutex;
|
JMutex m_peers_mutex;
|
||||||
|
|
||||||
ConnectionSendThread m_sendThread;
|
ConnectionSendThread m_sendThread;
|
||||||
|
@ -1096,3 +1095,4 @@ private:
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,13 +100,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
/*
|
/*
|
||||||
GUI related things
|
GUI related things
|
||||||
*/
|
*/
|
||||||
|
#define TTF_DEFAULT_FONT_SIZE (14)
|
||||||
// TODO: implement dpi-based scaling for windows and remove this hack
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define TTF_DEFAULT_FONT_SIZE (18)
|
|
||||||
#else
|
|
||||||
#define TTF_DEFAULT_FONT_SIZE (15)
|
|
||||||
#endif
|
|
||||||
#define DEFAULT_FONT_SIZE (10)
|
#define DEFAULT_FONT_SIZE (10)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,13 +27,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/numeric.h" // For IntervalLimiter
|
#include "util/numeric.h" // For IntervalLimiter
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "serialization.h" // For decompressZlib
|
#include "serialization.h" // For decompressZlib
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "clientobject.h"
|
#include "clientobject.h"
|
||||||
|
#include "content_object.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "itemdef.h"
|
#include "itemdef.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
@ -144,7 +145,7 @@ public:
|
||||||
TestCAO(IGameDef *gamedef, ClientEnvironment *env);
|
TestCAO(IGameDef *gamedef, ClientEnvironment *env);
|
||||||
virtual ~TestCAO();
|
virtual ~TestCAO();
|
||||||
|
|
||||||
ActiveObjectType getType() const
|
u8 getType() const
|
||||||
{
|
{
|
||||||
return ACTIVEOBJECT_TYPE_TEST;
|
return ACTIVEOBJECT_TYPE_TEST;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +289,7 @@ public:
|
||||||
ItemCAO(IGameDef *gamedef, ClientEnvironment *env);
|
ItemCAO(IGameDef *gamedef, ClientEnvironment *env);
|
||||||
virtual ~ItemCAO();
|
virtual ~ItemCAO();
|
||||||
|
|
||||||
ActiveObjectType getType() const
|
u8 getType() const
|
||||||
{
|
{
|
||||||
return ACTIVEOBJECT_TYPE_ITEM;
|
return ACTIVEOBJECT_TYPE_ITEM;
|
||||||
}
|
}
|
||||||
|
@ -962,7 +963,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
|
||||||
// Add a text node for showing the name
|
// Add a text node for showing the name
|
||||||
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
|
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
|
||||||
std::wstring wname = narrow_to_wide(m_name);
|
std::wstring wname = narrow_to_wide(m_name);
|
||||||
m_textnode = smgr->addTextSceneNode(gui->getSkin()->getFont(),
|
m_textnode = smgr->addTextSceneNode(gui->getBuiltInFont(),
|
||||||
wname.c_str(), video::SColor(255,255,255,255), node);
|
wname.c_str(), video::SColor(255,255,255,255), node);
|
||||||
m_textnode->grab();
|
m_textnode->grab();
|
||||||
m_textnode->setPosition(v3f(0, BS*1.1, 0));
|
m_textnode->setPosition(v3f(0, BS*1.1, 0));
|
||||||
|
|
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
|
#include "content_object.h"
|
||||||
#include "clientobject.h"
|
#include "clientobject.h"
|
||||||
#include "object_properties.h"
|
#include "object_properties.h"
|
||||||
#include "itemgroup.h"
|
#include "itemgroup.h"
|
||||||
|
@ -114,7 +115,7 @@ public:
|
||||||
return new GenericCAO(gamedef, env);
|
return new GenericCAO(gamedef, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ActiveObjectType getType() const
|
inline u8 getType() const
|
||||||
{
|
{
|
||||||
return ACTIVEOBJECT_TYPE_GENERIC;
|
return ACTIVEOBJECT_TYPE_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "content_cso.h"
|
#include "content_cso.h"
|
||||||
#include <IBillboardSceneNode.h>
|
#include <IBillboardSceneNode.h>
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
|
@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mapblock_mesh.h" // For MapBlock_LightColor() and MeshCollector
|
#include "mapblock_mesh.h" // For MapBlock_LightColor() and MeshCollector
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include <IMeshManipulator.h>
|
#include <IMeshManipulator.h>
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
|
@ -45,7 +45,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
// (compatible with ContentFeatures). If you specified 0,0,1,1
|
// (compatible with ContentFeatures). If you specified 0,0,1,1
|
||||||
// for each face, that would be the same as passing NULL.
|
// for each face, that would be the same as passing NULL.
|
||||||
void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
||||||
TileSpec *tiles, int tilecount, video::SColor &c, const f32* txc)
|
TileSpec *tiles, int tilecount,
|
||||||
|
video::SColor &c, const f32* txc)
|
||||||
{
|
{
|
||||||
assert(tilecount >= 1 && tilecount <= 6);
|
assert(tilecount >= 1 && tilecount <= 6);
|
||||||
|
|
||||||
|
@ -54,7 +55,8 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(txc == NULL) {
|
if(txc == NULL)
|
||||||
|
{
|
||||||
static const f32 txc_default[24] = {
|
static const f32 txc_default[24] = {
|
||||||
0,0,1,1,
|
0,0,1,1,
|
||||||
0,0,1,1,
|
0,0,1,1,
|
||||||
|
@ -158,16 +160,14 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
||||||
}
|
}
|
||||||
u16 indices[] = {0,1,2,2,3,0};
|
u16 indices[] = {0,1,2,2,3,0};
|
||||||
// Add to mesh collector
|
// Add to mesh collector
|
||||||
for (s32 j = 0; j < 24; j += 4) {
|
for(s32 j=0; j<24; j+=4)
|
||||||
int tileindex = MYMIN(j / 4, tilecount - 1);
|
{
|
||||||
collector->append(tiles[tileindex], vertices + j, 4, indices, 6);
|
int tileindex = MYMIN(j/4, tilecount-1);
|
||||||
|
collector->append(tiles[tileindex],
|
||||||
|
vertices+j, 4, indices, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: Fix alpha blending for special nodes
|
|
||||||
Currently only the last element rendered is blended correct
|
|
||||||
*/
|
|
||||||
void mapblock_mesh_generate_special(MeshMakeData *data,
|
void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
MeshCollector &collector)
|
MeshCollector &collector)
|
||||||
{
|
{
|
||||||
|
@ -191,6 +191,54 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
|
|
||||||
v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE;
|
v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
// Create selection mesh
|
||||||
|
v3s16 p = data->m_highlighted_pos_relative;
|
||||||
|
if (data->m_show_hud &&
|
||||||
|
(p.X >= 0) && (p.X < MAP_BLOCKSIZE) &&
|
||||||
|
(p.Y >= 0) && (p.Y < MAP_BLOCKSIZE) &&
|
||||||
|
(p.Z >= 0) && (p.Z < MAP_BLOCKSIZE)) {
|
||||||
|
|
||||||
|
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p);
|
||||||
|
if(n.getContent() != CONTENT_AIR) {
|
||||||
|
// Get selection mesh light level
|
||||||
|
static const v3s16 dirs[7] = {
|
||||||
|
v3s16( 0, 0, 0),
|
||||||
|
v3s16( 0, 1, 0),
|
||||||
|
v3s16( 0,-1, 0),
|
||||||
|
v3s16( 1, 0, 0),
|
||||||
|
v3s16(-1, 0, 0),
|
||||||
|
v3s16( 0, 0, 1),
|
||||||
|
v3s16( 0, 0,-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
u16 l = 0;
|
||||||
|
u16 l1 = 0;
|
||||||
|
for (u8 i = 0; i < 7; i++) {
|
||||||
|
MapNode n1 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dirs[i]);
|
||||||
|
l1 = getInteriorLight(n1, -4, nodedef);
|
||||||
|
if (l1 > l)
|
||||||
|
l = l1;
|
||||||
|
}
|
||||||
|
video::SColor c = MapBlock_LightColor(255, l, 0);
|
||||||
|
data->m_highlight_mesh_color = c;
|
||||||
|
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
|
||||||
|
TileSpec h_tile;
|
||||||
|
h_tile.material_flags |= MATERIAL_FLAG_HIGHLIGHTED;
|
||||||
|
h_tile.texture = tsrc->getTexture("halo.png",&h_tile.texture_id);
|
||||||
|
v3f pos = intToFloat(p, BS);
|
||||||
|
f32 d = 0.05 * BS;
|
||||||
|
for(std::vector<aabb3f>::iterator
|
||||||
|
i = boxes.begin();
|
||||||
|
i != boxes.end(); i++)
|
||||||
|
{
|
||||||
|
aabb3f box = *i;
|
||||||
|
box.MinEdge += v3f(-d, -d, -d) + pos;
|
||||||
|
box.MaxEdge += v3f(d, d, d) + pos;
|
||||||
|
makeCuboid(&collector, box, &h_tile, 1, c, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(s16 z = 0; z < MAP_BLOCKSIZE; z++)
|
for(s16 z = 0; z < MAP_BLOCKSIZE; z++)
|
||||||
for(s16 y = 0; y < MAP_BLOCKSIZE; y++)
|
for(s16 y = 0; y < MAP_BLOCKSIZE; y++)
|
||||||
for(s16 x = 0; x < MAP_BLOCKSIZE; x++)
|
for(s16 x = 0; x < MAP_BLOCKSIZE; x++)
|
||||||
|
@ -1421,65 +1469,77 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
|
|
||||||
content_t thiscontent = n.getContent();
|
content_t thiscontent = n.getContent();
|
||||||
std::string groupname = "connect_to_raillike"; // name of the group that enables connecting to raillike nodes of different kind
|
std::string groupname = "connect_to_raillike"; // name of the group that enables connecting to raillike nodes of different kind
|
||||||
int self_group = ((ItemGroupList) nodedef->get(n).groups)[groupname];
|
bool self_connect_to_raillike = ((ItemGroupList) nodedef->get(n).groups)[groupname] != 0;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_x).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_x).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_x).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_x).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_x.getContent() == thiscontent)
|
|| n_minus_x.getContent() == thiscontent)
|
||||||
is_rail_x[0] = true;
|
is_rail_x[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_x_minus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_x_minus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_x_minus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_x_minus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_x_minus_y.getContent() == thiscontent)
|
|| n_minus_x_minus_y.getContent() == thiscontent)
|
||||||
is_rail_x_minus_y[0] = true;
|
is_rail_x_minus_y[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_x_plus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_x_plus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_x_plus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_x_plus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_x_plus_y.getContent() == thiscontent)
|
|| n_minus_x_plus_y.getContent() == thiscontent)
|
||||||
is_rail_x_plus_y[0] = true;
|
is_rail_x_plus_y[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_x).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_x).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_x).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_x).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_x.getContent() == thiscontent)
|
|| n_plus_x.getContent() == thiscontent)
|
||||||
is_rail_x[1] = true;
|
is_rail_x[1] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_x_minus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_x_minus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_x_minus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_x_minus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_x_minus_y.getContent() == thiscontent)
|
|| n_plus_x_minus_y.getContent() == thiscontent)
|
||||||
is_rail_x_minus_y[1] = true;
|
is_rail_x_minus_y[1] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_x_plus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_x_plus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_x_plus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_x_plus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_x_plus_y.getContent() == thiscontent)
|
|| n_plus_x_plus_y.getContent() == thiscontent)
|
||||||
is_rail_x_plus_y[1] = true;
|
is_rail_x_plus_y[1] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_z).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_z).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_z).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_z).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_z.getContent() == thiscontent)
|
|| n_minus_z.getContent() == thiscontent)
|
||||||
is_rail_z[0] = true;
|
is_rail_z[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_z_minus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_z_minus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_z_minus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_z_minus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_z_minus_y.getContent() == thiscontent)
|
|| n_minus_z_minus_y.getContent() == thiscontent)
|
||||||
is_rail_z_minus_y[0] = true;
|
is_rail_z_minus_y[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_minus_z_plus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_minus_z_plus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_minus_z_plus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_minus_z_plus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_minus_z_plus_y.getContent() == thiscontent)
|
|| n_minus_z_plus_y.getContent() == thiscontent)
|
||||||
is_rail_z_plus_y[0] = true;
|
is_rail_z_plus_y[0] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_z).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_z).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_z).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_z).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_z.getContent() == thiscontent)
|
|| n_plus_z.getContent() == thiscontent)
|
||||||
is_rail_z[1] = true;
|
is_rail_z[1] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_z_minus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_z_minus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_z_minus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_z_minus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_z_minus_y.getContent() == thiscontent)
|
|| n_plus_z_minus_y.getContent() == thiscontent)
|
||||||
is_rail_z_minus_y[1] = true;
|
is_rail_z_minus_y[1] = true;
|
||||||
|
|
||||||
if ((nodedef->get(n_plus_z_plus_y).drawtype == NDT_RAILLIKE
|
if ((nodedef->get(n_plus_z_plus_y).drawtype == NDT_RAILLIKE
|
||||||
&& ((ItemGroupList) nodedef->get(n_plus_z_plus_y).groups)[groupname] != self_group)
|
&& ((ItemGroupList) nodedef->get(n_plus_z_plus_y).groups)[groupname] != 0
|
||||||
|
&& self_connect_to_raillike)
|
||||||
|| n_plus_z_plus_y.getContent() == thiscontent)
|
|| n_plus_z_plus_y.getContent() == thiscontent)
|
||||||
is_rail_z_plus_y[1] = true;
|
is_rail_z_plus_y[1] = true;
|
||||||
|
|
||||||
|
@ -1706,55 +1766,5 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
break;}
|
break;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Caused by incorrect alpha blending, selection mesh needs to be created as
|
|
||||||
last element to ensure it gets blended correct over nodes with alpha channel
|
|
||||||
*/
|
|
||||||
// Create selection mesh
|
|
||||||
v3s16 p = data->m_highlighted_pos_relative;
|
|
||||||
if (data->m_show_hud &&
|
|
||||||
(p.X >= 0) && (p.X < MAP_BLOCKSIZE) &&
|
|
||||||
(p.Y >= 0) && (p.Y < MAP_BLOCKSIZE) &&
|
|
||||||
(p.Z >= 0) && (p.Z < MAP_BLOCKSIZE)) {
|
|
||||||
|
|
||||||
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p);
|
|
||||||
if(n.getContent() != CONTENT_AIR) {
|
|
||||||
// Get selection mesh light level
|
|
||||||
static const v3s16 dirs[7] = {
|
|
||||||
v3s16( 0, 0, 0),
|
|
||||||
v3s16( 0, 1, 0),
|
|
||||||
v3s16( 0,-1, 0),
|
|
||||||
v3s16( 1, 0, 0),
|
|
||||||
v3s16(-1, 0, 0),
|
|
||||||
v3s16( 0, 0, 1),
|
|
||||||
v3s16( 0, 0,-1)
|
|
||||||
};
|
|
||||||
|
|
||||||
u16 l = 0;
|
|
||||||
u16 l1 = 0;
|
|
||||||
for (u8 i = 0; i < 7; i++) {
|
|
||||||
MapNode n1 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dirs[i]);
|
|
||||||
l1 = getInteriorLight(n1, -4, nodedef);
|
|
||||||
if (l1 > l)
|
|
||||||
l = l1;
|
|
||||||
}
|
|
||||||
video::SColor c = MapBlock_LightColor(255, l, 0);
|
|
||||||
data->m_highlight_mesh_color = c;
|
|
||||||
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
|
|
||||||
TileSpec h_tile;
|
|
||||||
h_tile.material_flags |= MATERIAL_FLAG_HIGHLIGHTED;
|
|
||||||
h_tile.texture = tsrc->getTexture("halo.png",&h_tile.texture_id);
|
|
||||||
v3f pos = intToFloat(p, BS);
|
|
||||||
f32 d = 0.05 * BS;
|
|
||||||
for (std::vector<aabb3f>::iterator i = boxes.begin();
|
|
||||||
i != boxes.end(); i++) {
|
|
||||||
aabb3f box = *i;
|
|
||||||
box.MinEdge += v3f(-d, -d, -d) + pos;
|
|
||||||
box.MaxEdge += v3f(d, d, d) + pos;
|
|
||||||
makeCuboid(&collector, box, &h_tile, 1, c, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GAME_PARAMS_H__
|
#ifndef CONTENT_OBJECT_HEADER
|
||||||
#define __GAME_PARAMS_H__
|
#define CONTENT_OBJECT_HEADER
|
||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#define ACTIVEOBJECT_TYPE_TEST 1
|
||||||
|
#define ACTIVEOBJECT_TYPE_ITEM 2
|
||||||
|
#define ACTIVEOBJECT_TYPE_RAT 3
|
||||||
|
#define ACTIVEOBJECT_TYPE_OERKKI1 4
|
||||||
|
#define ACTIVEOBJECT_TYPE_FIREFLY 5
|
||||||
|
#define ACTIVEOBJECT_TYPE_MOBV2 6
|
||||||
|
|
||||||
struct GameParams {
|
#define ACTIVEOBJECT_TYPE_LUAENTITY 7
|
||||||
u16 socket_port;
|
|
||||||
std::string world_path;
|
// Special type, not stored as a static object
|
||||||
SubgameSpec game_spec;
|
#define ACTIVEOBJECT_TYPE_PLAYER 100
|
||||||
bool is_dedicated_server;
|
|
||||||
int log_level;
|
// Special type, only exists as CAO
|
||||||
};
|
#define ACTIVEOBJECT_TYPE_GENERIC 101
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,13 +29,60 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "tool.h" // For ToolCapabilities
|
#include "tool.h" // For ToolCapabilities
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "server.h"
|
|
||||||
#include "scripting_game.h"
|
#include "scripting_game.h"
|
||||||
#include "genericobject.h"
|
#include "genericobject.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
||||||
|
|
||||||
|
/*
|
||||||
|
DummyLoadSAO
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DummyLoadSAO : public ServerActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DummyLoadSAO(ServerEnvironment *env, v3f pos, u8 type):
|
||||||
|
ServerActiveObject(env, pos)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(type, create);
|
||||||
|
}
|
||||||
|
// Pretend to be the test object (to fool the client)
|
||||||
|
u8 getType() const
|
||||||
|
{ return ACTIVEOBJECT_TYPE_TEST; }
|
||||||
|
// And never save to disk
|
||||||
|
bool isStaticAllowed() const
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
|
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
return new DummyLoadSAO(env, pos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
m_removed = true;
|
||||||
|
infostream<<"DummyLoadSAO step"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getCollisionBox(aabb3f *toset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool collideWithObjects() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prototype (registers item for deserialization)
|
||||||
|
DummyLoadSAO proto1_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_RAT);
|
||||||
|
DummyLoadSAO proto2_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_OERKKI1);
|
||||||
|
DummyLoadSAO proto3_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_FIREFLY);
|
||||||
|
DummyLoadSAO proto4_DummyLoadSAO(NULL, v3f(0,0,0), ACTIVEOBJECT_TYPE_MOBV2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TestSAO
|
TestSAO
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +97,7 @@ public:
|
||||||
{
|
{
|
||||||
ServerActiveObject::registerType(getType(), create);
|
ServerActiveObject::registerType(getType(), create);
|
||||||
}
|
}
|
||||||
ActiveObjectType getType() const
|
u8 getType() const
|
||||||
{ return ACTIVEOBJECT_TYPE_TEST; }
|
{ return ACTIVEOBJECT_TYPE_TEST; }
|
||||||
|
|
||||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||||
|
@ -91,7 +138,7 @@ public:
|
||||||
data += itos(m_base_position.Z);
|
data += itos(m_base_position.Z);
|
||||||
|
|
||||||
ActiveObjectMessage aom(getId(), false, data);
|
ActiveObjectMessage aom(getId(), false, data);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +158,203 @@ private:
|
||||||
// Prototype (registers item for deserialization)
|
// Prototype (registers item for deserialization)
|
||||||
TestSAO proto_TestSAO(NULL, v3f(0,0,0));
|
TestSAO proto_TestSAO(NULL, v3f(0,0,0));
|
||||||
|
|
||||||
|
/*
|
||||||
|
ItemSAO
|
||||||
|
|
||||||
|
DEPRECATED: New dropped items are implemented in Lua; see
|
||||||
|
builtin/item_entity.lua.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ItemSAO : public ServerActiveObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
u8 getType() const
|
||||||
|
{ return ACTIVEOBJECT_TYPE_ITEM; }
|
||||||
|
|
||||||
|
float getMinimumSavedMovement()
|
||||||
|
{ return 0.1*BS; }
|
||||||
|
|
||||||
|
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||||
|
const std::string &data)
|
||||||
|
{
|
||||||
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
char buf[1];
|
||||||
|
// read version
|
||||||
|
is.read(buf, 1);
|
||||||
|
u8 version = buf[0];
|
||||||
|
// check if version is supported
|
||||||
|
if(version != 0)
|
||||||
|
return NULL;
|
||||||
|
std::string itemstring = deSerializeString(is);
|
||||||
|
infostream<<"create(): Creating item \""
|
||||||
|
<<itemstring<<"\""<<std::endl;
|
||||||
|
return new ItemSAO(env, pos, itemstring);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemSAO(ServerEnvironment *env, v3f pos,
|
||||||
|
const std::string &itemstring):
|
||||||
|
ServerActiveObject(env, pos),
|
||||||
|
m_itemstring(itemstring),
|
||||||
|
m_itemstring_changed(false),
|
||||||
|
m_speed_f(0,0,0),
|
||||||
|
m_last_sent_position(0,0,0)
|
||||||
|
{
|
||||||
|
ServerActiveObject::registerType(getType(), create);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(float dtime, bool send_recommended)
|
||||||
|
{
|
||||||
|
ScopeProfiler sp2(g_profiler, "step avg", SPT_AVG);
|
||||||
|
|
||||||
|
assert(m_env);
|
||||||
|
|
||||||
|
const float interval = 0.2;
|
||||||
|
if(m_move_interval.step(dtime, interval)==false)
|
||||||
|
return;
|
||||||
|
dtime = interval;
|
||||||
|
|
||||||
|
core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
|
||||||
|
collisionMoveResult moveresult;
|
||||||
|
// Apply gravity
|
||||||
|
m_speed_f += v3f(0, -dtime*9.81*BS, 0);
|
||||||
|
// Maximum movement without glitches
|
||||||
|
f32 pos_max_d = BS*0.25;
|
||||||
|
// Limit speed
|
||||||
|
if(m_speed_f.getLength()*dtime > pos_max_d)
|
||||||
|
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
|
||||||
|
v3f pos_f = getBasePosition();
|
||||||
|
v3f accel_f = v3f(0,0,0);
|
||||||
|
f32 stepheight = 0;
|
||||||
|
moveresult = collisionMoveSimple(m_env,m_env->getGameDef(),
|
||||||
|
pos_max_d, box, stepheight, dtime,
|
||||||
|
pos_f, m_speed_f, accel_f);
|
||||||
|
|
||||||
|
if(send_recommended == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
|
||||||
|
{
|
||||||
|
setBasePosition(pos_f);
|
||||||
|
m_last_sent_position = pos_f;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command (0 = update position)
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
if(m_itemstring_changed)
|
||||||
|
{
|
||||||
|
m_itemstring_changed = false;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command (1 = update itemstring)
|
||||||
|
writeU8(os, 1);
|
||||||
|
// itemstring
|
||||||
|
os<<serializeString(m_itemstring);
|
||||||
|
// create message and add to list
|
||||||
|
ActiveObjectMessage aom(getId(), false, os.str());
|
||||||
|
m_messages_out.push_back(aom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getClientInitializationData(u16 protocol_version)
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
// pos
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
// itemstring
|
||||||
|
os<<serializeString(m_itemstring);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getStaticData()
|
||||||
|
{
|
||||||
|
infostream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// version
|
||||||
|
writeU8(os, 0);
|
||||||
|
// itemstring
|
||||||
|
os<<serializeString(m_itemstring);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack createItemStack()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
IItemDefManager *idef = m_env->getGameDef()->idef();
|
||||||
|
ItemStack item;
|
||||||
|
item.deSerialize(m_itemstring, idef);
|
||||||
|
infostream<<__FUNCTION_NAME<<": m_itemstring=\""<<m_itemstring
|
||||||
|
<<"\" -> item=\""<<item.getItemString()<<"\""
|
||||||
|
<<std::endl;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
infostream<<__FUNCTION_NAME<<": serialization error: "
|
||||||
|
<<"m_itemstring=\""<<m_itemstring<<"\""<<std::endl;
|
||||||
|
return ItemStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int punch(v3f dir,
|
||||||
|
const ToolCapabilities *toolcap,
|
||||||
|
ServerActiveObject *puncher,
|
||||||
|
float time_from_last_punch)
|
||||||
|
{
|
||||||
|
// Take item into inventory
|
||||||
|
ItemStack item = createItemStack();
|
||||||
|
Inventory *inv = puncher->getInventory();
|
||||||
|
if(inv != NULL)
|
||||||
|
{
|
||||||
|
std::string wieldlist = puncher->getWieldList();
|
||||||
|
ItemStack leftover = inv->addItem(wieldlist, item);
|
||||||
|
puncher->setInventoryModified();
|
||||||
|
if(leftover.empty())
|
||||||
|
{
|
||||||
|
m_removed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_itemstring = leftover.getItemString();
|
||||||
|
m_itemstring_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getCollisionBox(aabb3f *toset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool collideWithObjects() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_itemstring;
|
||||||
|
bool m_itemstring_changed;
|
||||||
|
v3f m_speed_f;
|
||||||
|
v3f m_last_sent_position;
|
||||||
|
IntervalLimiter m_move_interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prototype (registers item for deserialization)
|
||||||
|
ItemSAO proto_ItemSAO(NULL, v3f(0,0,0), "");
|
||||||
|
|
||||||
|
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
|
||||||
|
const std::string &itemstring)
|
||||||
|
{
|
||||||
|
return new ItemSAO(env, pos, itemstring);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LuaEntitySAO
|
LuaEntitySAO
|
||||||
*/
|
*/
|
||||||
|
@ -233,7 +477,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = getPropertyPacket();
|
std::string str = getPropertyPacket();
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attached, check that our parent is still there. If it isn't, detach.
|
// If attached, check that our parent is still there. If it isn't, detach.
|
||||||
|
@ -320,7 +564,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
m_armor_groups);
|
m_armor_groups);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_animation_sent == false){
|
if(m_animation_sent == false){
|
||||||
|
@ -328,7 +572,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
|
std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_bone_position_sent == false){
|
if(m_bone_position_sent == false){
|
||||||
|
@ -337,7 +581,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
|
std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +590,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
|
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +705,7 @@ int LuaEntitySAO::punch(v3f dir,
|
||||||
std::string str = gob_cmd_punched(result.damage, getHP());
|
std::string str = gob_cmd_punched(result.damage, getHP());
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getHP() == 0)
|
if(getHP() == 0)
|
||||||
|
@ -610,7 +854,7 @@ void LuaEntitySAO::setTextureMod(const std::string &mod)
|
||||||
std::string str = gob_cmd_set_texture_mod(mod);
|
std::string str = gob_cmd_set_texture_mod(mod);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
|
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
|
||||||
|
@ -624,7 +868,7 @@ void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
|
||||||
);
|
);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaEntitySAO::getName()
|
std::string LuaEntitySAO::getName()
|
||||||
|
@ -664,7 +908,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||||
);
|
);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), false, str);
|
ActiveObjectMessage aom(getId(), false, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaEntitySAO::getCollisionBox(aabb3f *toset) {
|
bool LuaEntitySAO::getCollisionBox(aabb3f *toset) {
|
||||||
|
@ -717,6 +961,11 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
||||||
m_attachment_parent_id(0),
|
m_attachment_parent_id(0),
|
||||||
m_attachment_sent(false),
|
m_attachment_sent(false),
|
||||||
// public
|
// public
|
||||||
|
m_moved(false),
|
||||||
|
m_inventory_not_sent(false),
|
||||||
|
m_hp_not_sent(false),
|
||||||
|
m_breath_not_sent(false),
|
||||||
|
m_wielded_item_not_sent(false),
|
||||||
m_physics_override_speed(1),
|
m_physics_override_speed(1),
|
||||||
m_physics_override_jump(1),
|
m_physics_override_jump(1),
|
||||||
m_physics_override_gravity(1),
|
m_physics_override_gravity(1),
|
||||||
|
@ -856,7 +1105,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = getPropertyPacket();
|
std::string str = getPropertyPacket();
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attached, check that our parent is still there. If it isn't, detach.
|
// If attached, check that our parent is still there. If it isn't, detach.
|
||||||
|
@ -867,7 +1116,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
m_attachment_position = v3f(0,0,0);
|
m_attachment_position = v3f(0,0,0);
|
||||||
m_attachment_rotation = v3f(0,0,0);
|
m_attachment_rotation = v3f(0,0,0);
|
||||||
m_player->setPosition(m_last_good_position);
|
m_player->setPosition(m_last_good_position);
|
||||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
m_moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dstream<<"PlayerSAO::step: dtime: "<<dtime<<std::endl;
|
//dstream<<"PlayerSAO::step: dtime: "<<dtime<<std::endl;
|
||||||
|
@ -919,16 +1168,22 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
);
|
);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), false, str);
|
ActiveObjectMessage aom(getId(), false, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_armor_groups_sent == false) {
|
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;
|
m_armor_groups_sent = true;
|
||||||
std::string str = gob_cmd_update_armor_groups(
|
std::string str = gob_cmd_update_armor_groups(
|
||||||
m_armor_groups);
|
m_armor_groups);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_physics_override_sent == false){
|
if(m_physics_override_sent == false){
|
||||||
|
@ -938,7 +1193,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
m_physics_override_sneak, m_physics_override_sneak_glitch);
|
m_physics_override_sneak, m_physics_override_sneak_glitch);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_animation_sent == false){
|
if(m_animation_sent == false){
|
||||||
|
@ -946,7 +1201,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
|
std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_bone_position_sent == false){
|
if(m_bone_position_sent == false){
|
||||||
|
@ -955,7 +1210,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
|
std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,7 +1219,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
|
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,7 +1237,8 @@ void PlayerSAO::setPos(v3f pos)
|
||||||
m_player->setPosition(pos);
|
m_player->setPosition(pos);
|
||||||
// Movement caused by this command is always valid
|
// Movement caused by this command is always valid
|
||||||
m_last_good_position = pos;
|
m_last_good_position = pos;
|
||||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
// Force position change on client
|
||||||
|
m_moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSAO::moveTo(v3f pos, bool continuous)
|
void PlayerSAO::moveTo(v3f pos, bool continuous)
|
||||||
|
@ -992,19 +1248,22 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
|
||||||
m_player->setPosition(pos);
|
m_player->setPosition(pos);
|
||||||
// Movement caused by this command is always valid
|
// Movement caused by this command is always valid
|
||||||
m_last_good_position = pos;
|
m_last_good_position = pos;
|
||||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
// Force position change on client
|
||||||
|
m_moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSAO::setYaw(float yaw)
|
void PlayerSAO::setYaw(float yaw)
|
||||||
{
|
{
|
||||||
m_player->setYaw(yaw);
|
m_player->setYaw(yaw);
|
||||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
// Force change on client
|
||||||
|
m_moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSAO::setPitch(float pitch)
|
void PlayerSAO::setPitch(float pitch)
|
||||||
{
|
{
|
||||||
m_player->setPitch(pitch);
|
m_player->setPitch(pitch);
|
||||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
// Force change on client
|
||||||
|
m_moved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PlayerSAO::punch(v3f dir,
|
int PlayerSAO::punch(v3f dir,
|
||||||
|
@ -1025,7 +1284,7 @@ int PlayerSAO::punch(v3f dir,
|
||||||
std::string str = gob_cmd_punched(0, getHP());
|
std::string str = gob_cmd_punched(0, getHP());
|
||||||
// create message and add to list
|
// create message and add to list
|
||||||
ActiveObjectMessage aom(getId(), true, str);
|
ActiveObjectMessage aom(getId(), true, str);
|
||||||
m_messages_out.push(aom);
|
m_messages_out.push_back(aom);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1067,18 +1326,27 @@ void PlayerSAO::setHP(s16 hp)
|
||||||
{
|
{
|
||||||
s16 oldhp = m_player->hp;
|
s16 oldhp = m_player->hp;
|
||||||
|
|
||||||
if (hp < 0)
|
if(hp < 0)
|
||||||
hp = 0;
|
hp = 0;
|
||||||
else if (hp > PLAYER_MAX_HP)
|
else if(hp > PLAYER_MAX_HP)
|
||||||
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;
|
m_player->hp = hp;
|
||||||
|
|
||||||
if (oldhp > hp)
|
if(hp != oldhp) {
|
||||||
m_damage += (oldhp - hp);
|
m_hp_not_sent = true;
|
||||||
|
if(oldhp > hp)
|
||||||
|
m_damage += oldhp - hp;
|
||||||
|
}
|
||||||
|
|
||||||
// Update properties on death
|
// Update properties on death
|
||||||
if ((hp == 0) != (oldhp == 0))
|
if((hp == 0) != (oldhp == 0))
|
||||||
m_properties_sent = false;
|
m_properties_sent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,6 +1425,11 @@ InventoryLocation PlayerSAO::getInventoryLocation() const
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerSAO::setInventoryModified()
|
||||||
|
{
|
||||||
|
m_inventory_not_sent = true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PlayerSAO::getWieldList() const
|
std::string PlayerSAO::getWieldList() const
|
||||||
{
|
{
|
||||||
return "main";
|
return "main";
|
||||||
|
@ -1169,8 +1442,10 @@ int PlayerSAO::getWieldIndex() const
|
||||||
|
|
||||||
void PlayerSAO::setWieldIndex(int i)
|
void PlayerSAO::setWieldIndex(int i)
|
||||||
{
|
{
|
||||||
if(i != m_wield_index) {
|
if(i != m_wield_index)
|
||||||
|
{
|
||||||
m_wield_index = i;
|
m_wield_index = i;
|
||||||
|
m_wielded_item_not_sent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,6 +1512,7 @@ bool PlayerSAO::checkMovementCheat()
|
||||||
<<" moved too fast; resetting position"
|
<<" moved too fast; resetting position"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
m_player->setPosition(m_last_good_position);
|
m_player->setPosition(m_last_good_position);
|
||||||
|
m_moved = true;
|
||||||
cheated = true;
|
cheated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define CONTENT_SAO_HEADER
|
#define CONTENT_SAO_HEADER
|
||||||
|
|
||||||
#include "serverobject.h"
|
#include "serverobject.h"
|
||||||
|
#include "content_object.h"
|
||||||
#include "itemgroup.h"
|
#include "itemgroup.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "object_properties.h"
|
#include "object_properties.h"
|
||||||
|
|
||||||
|
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
|
||||||
|
const std::string &itemstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LuaEntitySAO needs some internals exposed.
|
LuaEntitySAO needs some internals exposed.
|
||||||
*/
|
*/
|
||||||
|
@ -35,9 +39,9 @@ public:
|
||||||
LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||||
const std::string &name, const std::string &state);
|
const std::string &name, const std::string &state);
|
||||||
~LuaEntitySAO();
|
~LuaEntitySAO();
|
||||||
ActiveObjectType getType() const
|
u8 getType() const
|
||||||
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
|
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
|
||||||
ActiveObjectType getSendType() const
|
u8 getSendType() const
|
||||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||||
virtual void addedToEnvironment(u32 dtime_s);
|
virtual void addedToEnvironment(u32 dtime_s);
|
||||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||||
|
@ -154,9 +158,9 @@ public:
|
||||||
PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
||||||
const std::set<std::string> &privs, bool is_singleplayer);
|
const std::set<std::string> &privs, bool is_singleplayer);
|
||||||
~PlayerSAO();
|
~PlayerSAO();
|
||||||
ActiveObjectType getType() const
|
u8 getType() const
|
||||||
{ return ACTIVEOBJECT_TYPE_PLAYER; }
|
{ return ACTIVEOBJECT_TYPE_PLAYER; }
|
||||||
ActiveObjectType getSendType() const
|
u8 getSendType() const
|
||||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||||
std::string getDescription();
|
std::string getDescription();
|
||||||
|
|
||||||
|
@ -205,6 +209,7 @@ public:
|
||||||
Inventory* getInventory();
|
Inventory* getInventory();
|
||||||
const Inventory* getInventory() const;
|
const Inventory* getInventory() const;
|
||||||
InventoryLocation getInventoryLocation() const;
|
InventoryLocation getInventoryLocation() const;
|
||||||
|
void setInventoryModified();
|
||||||
std::string getWieldList() const;
|
std::string getWieldList() const;
|
||||||
int getWieldIndex() const;
|
int getWieldIndex() const;
|
||||||
void setWieldIndex(int i);
|
void setWieldIndex(int i);
|
||||||
|
@ -314,6 +319,13 @@ private:
|
||||||
bool m_attachment_sent;
|
bool m_attachment_sent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// Some flags used by Server
|
||||||
|
bool m_moved;
|
||||||
|
bool m_inventory_not_sent;
|
||||||
|
bool m_hp_not_sent;
|
||||||
|
bool m_breath_not_sent;
|
||||||
|
bool m_wielded_item_not_sent;
|
||||||
|
|
||||||
float m_physics_override_speed;
|
float m_physics_override_speed;
|
||||||
float m_physics_override_jump;
|
float m_physics_override_jump;
|
||||||
float m_physics_override_gravity;
|
float m_physics_override_gravity;
|
||||||
|
|
|
@ -418,28 +418,27 @@ bool CraftDefinitionShaped::check(const CraftInput &input, IGameDef *gamedef) co
|
||||||
return false; // it was empty
|
return false; // it was empty
|
||||||
|
|
||||||
// Different sizes?
|
// Different sizes?
|
||||||
if(inp_max_x - inp_min_x != rec_max_x - rec_min_x ||
|
if(inp_max_x - inp_min_x != rec_max_x - rec_min_x)
|
||||||
inp_max_y - inp_min_y != rec_max_y - rec_min_y)
|
return false;
|
||||||
|
if(inp_max_y - inp_min_y != rec_max_y - rec_min_y)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Verify that all item names in the bounding box are equal
|
// Verify that all item names in the bounding box are equal
|
||||||
unsigned int w = inp_max_x - inp_min_x + 1;
|
unsigned int w = inp_max_x - inp_min_x + 1;
|
||||||
unsigned int h = inp_max_y - inp_min_y + 1;
|
unsigned int h = inp_max_y - inp_min_y + 1;
|
||||||
|
for(unsigned int y=0; y<h; y++)
|
||||||
|
for(unsigned int x=0; x<w; x++)
|
||||||
|
{
|
||||||
|
unsigned int inp_x = inp_min_x + x;
|
||||||
|
unsigned int inp_y = inp_min_y + y;
|
||||||
|
unsigned int rec_x = rec_min_x + x;
|
||||||
|
unsigned int rec_y = rec_min_y + y;
|
||||||
|
|
||||||
for(unsigned int y=0; y < h; y++) {
|
if(!inputItemMatchesRecipe(
|
||||||
unsigned int inp_y = (inp_min_y + y) * inp_width;
|
inp_names[inp_y * inp_width + inp_x],
|
||||||
unsigned int rec_y = (rec_min_y + y) * rec_width;
|
rec_names[rec_y * rec_width + rec_x], gamedef->idef())
|
||||||
|
){
|
||||||
for(unsigned int x=0; x < w; x++) {
|
return false;
|
||||||
unsigned int inp_x = inp_min_x + x;
|
|
||||||
unsigned int rec_x = rec_min_x + x;
|
|
||||||
|
|
||||||
if(!inputItemMatchesRecipe(
|
|
||||||
inp_names[inp_y + inp_x],
|
|
||||||
rec_names[rec_y + rec_x], gamedef->idef())
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,38 +18,64 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Dummy database class
|
Dummy "database" class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "database-dummy.h"
|
#include "database-dummy.h"
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
#include "mapsector.h"
|
||||||
|
#include "mapblock.h"
|
||||||
|
#include "serialization.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
bool Database_Dummy::saveBlock(const v3s16 &pos, const std::string &data)
|
Database_Dummy::Database_Dummy(ServerMap *map)
|
||||||
{
|
{
|
||||||
m_database[getBlockAsInteger(pos)] = data;
|
srvmap = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Database_Dummy::Initialized(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database_Dummy::beginSave() {}
|
||||||
|
void Database_Dummy::endSave() {}
|
||||||
|
|
||||||
|
bool Database_Dummy::saveBlock(v3s16 blockpos, std::string &data)
|
||||||
|
{
|
||||||
|
m_database[getBlockAsInteger(blockpos)] = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database_Dummy::loadBlock(const v3s16 &pos)
|
std::string Database_Dummy::loadBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
s64 i = getBlockAsInteger(pos);
|
if (m_database.count(getBlockAsInteger(blockpos)))
|
||||||
if (m_database.count(i))
|
return m_database[getBlockAsInteger(blockpos)];
|
||||||
return m_database[i];
|
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_Dummy::deleteBlock(const v3s16 &pos)
|
bool Database_Dummy::deleteBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
m_database.erase(getBlockAsInteger(pos));
|
m_database.erase(getBlockAsInteger(blockpos));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_Dummy::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
void Database_Dummy::listAllLoadableBlocks(std::list<v3s16> &dst)
|
||||||
{
|
{
|
||||||
for (std::map<s64, std::string>::const_iterator x = m_database.begin();
|
for(std::map<u64, std::string>::iterator x = m_database.begin(); x != m_database.end(); ++x)
|
||||||
x != m_database.end(); ++x) {
|
{
|
||||||
dst.push_back(getIntegerAsBlock(x->first));
|
v3s16 p = getIntegerAsBlock(x->first);
|
||||||
|
//dstream<<"block_i="<<block_i<<" p="<<PP(p)<<std::endl;
|
||||||
|
dst.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Database_Dummy::~Database_Dummy()
|
||||||
|
{
|
||||||
|
m_database.clear();
|
||||||
|
}
|
||||||
|
|
|
@ -25,17 +25,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "irrlichttypes.h"
|
#include "irrlichttypes.h"
|
||||||
|
|
||||||
|
class ServerMap;
|
||||||
|
|
||||||
class Database_Dummy : public Database
|
class Database_Dummy : public Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data);
|
Database_Dummy(ServerMap *map);
|
||||||
virtual std::string loadBlock(const v3s16 &pos);
|
virtual void beginSave();
|
||||||
virtual bool deleteBlock(const v3s16 &pos);
|
virtual void endSave();
|
||||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
virtual bool saveBlock(v3s16 blockpos, std::string &data);
|
||||||
|
virtual std::string loadBlock(v3s16 blockpos);
|
||||||
|
virtual bool deleteBlock(v3s16 blockpos);
|
||||||
|
virtual void listAllLoadableBlocks(std::list<v3s16> &dst);
|
||||||
|
virtual int Initialized(void);
|
||||||
|
~Database_Dummy();
|
||||||
private:
|
private:
|
||||||
std::map<s64, std::string> m_database;
|
ServerMap *srvmap;
|
||||||
|
std::map<u64, std::string> m_database;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -22,54 +22,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#if USE_LEVELDB
|
#if USE_LEVELDB
|
||||||
|
|
||||||
#include "database-leveldb.h"
|
#include "database-leveldb.h"
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
#include "filesys.h"
|
|
||||||
#include "exceptions.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
#include "mapsector.h"
|
||||||
|
#include "mapblock.h"
|
||||||
|
#include "serialization.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "filesys.h"
|
||||||
|
|
||||||
#define ENSURE_STATUS_OK(s) \
|
#define ENSURE_STATUS_OK(s) \
|
||||||
if (!(s).ok()) { \
|
if (!(s).ok()) { \
|
||||||
throw FileNotGoodException(std::string("LevelDB error: ") + \
|
throw FileNotGoodException(std::string("LevelDB error: ") + (s).ToString()); \
|
||||||
(s).ToString()); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Database_LevelDB::Database_LevelDB(ServerMap *map, std::string savedir)
|
||||||
Database_LevelDB::Database_LevelDB(const std::string &savedir)
|
|
||||||
{
|
{
|
||||||
leveldb::Options options;
|
leveldb::Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
leveldb::Status status = leveldb::DB::Open(options,
|
leveldb::Status status = leveldb::DB::Open(options, savedir + DIR_DELIM + "map.db", &m_database);
|
||||||
savedir + DIR_DELIM + "map.db", &m_database);
|
|
||||||
ENSURE_STATUS_OK(status);
|
ENSURE_STATUS_OK(status);
|
||||||
|
srvmap = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database_LevelDB::~Database_LevelDB()
|
int Database_LevelDB::Initialized(void)
|
||||||
{
|
{
|
||||||
delete m_database;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data)
|
void Database_LevelDB::beginSave() {}
|
||||||
|
void Database_LevelDB::endSave() {}
|
||||||
|
|
||||||
|
bool Database_LevelDB::saveBlock(v3s16 blockpos, std::string &data)
|
||||||
{
|
{
|
||||||
leveldb::Status status = m_database->Put(leveldb::WriteOptions(),
|
leveldb::Status status = m_database->Put(leveldb::WriteOptions(),
|
||||||
i64tos(getBlockAsInteger(pos)), data);
|
i64tos(getBlockAsInteger(blockpos)), data);
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
errorstream << "WARNING: saveBlock: LevelDB error saving block "
|
errorstream << "WARNING: saveBlock: LevelDB error saving block "
|
||||||
<< PP(pos) << ": " << status.ToString() << std::endl;
|
<< PP(blockpos) << ": " << status.ToString() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database_LevelDB::loadBlock(const v3s16 &pos)
|
std::string Database_LevelDB::loadBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
std::string datastr;
|
std::string datastr;
|
||||||
leveldb::Status status = m_database->Get(leveldb::ReadOptions(),
|
leveldb::Status status = m_database->Get(leveldb::ReadOptions(),
|
||||||
i64tos(getBlockAsInteger(pos)), &datastr);
|
i64tos(getBlockAsInteger(blockpos)), &datastr);
|
||||||
|
|
||||||
if(status.ok())
|
if(status.ok())
|
||||||
return datastr;
|
return datastr;
|
||||||
|
@ -77,20 +80,20 @@ std::string Database_LevelDB::loadBlock(const v3s16 &pos)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_LevelDB::deleteBlock(const v3s16 &pos)
|
bool Database_LevelDB::deleteBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
leveldb::Status status = m_database->Delete(leveldb::WriteOptions(),
|
leveldb::Status status = m_database->Delete(leveldb::WriteOptions(),
|
||||||
i64tos(getBlockAsInteger(pos)));
|
i64tos(getBlockAsInteger(blockpos)));
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
errorstream << "WARNING: deleteBlock: LevelDB error deleting block "
|
errorstream << "WARNING: deleteBlock: LevelDB error deleting block "
|
||||||
<< PP(pos) << ": " << status.ToString() << std::endl;
|
<< PP(blockpos) << ": " << status.ToString() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
void Database_LevelDB::listAllLoadableBlocks(std::list<v3s16> &dst)
|
||||||
{
|
{
|
||||||
leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions());
|
leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions());
|
||||||
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
||||||
|
@ -100,5 +103,8 @@ void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
||||||
delete it;
|
delete it;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_LEVELDB
|
Database_LevelDB::~Database_LevelDB()
|
||||||
|
{
|
||||||
|
delete m_database;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -28,22 +28,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
class ServerMap;
|
||||||
|
|
||||||
class Database_LevelDB : public Database
|
class Database_LevelDB : public Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Database_LevelDB(const std::string &savedir);
|
Database_LevelDB(ServerMap *map, std::string savedir);
|
||||||
|
virtual void beginSave();
|
||||||
|
virtual void endSave();
|
||||||
|
virtual bool saveBlock(v3s16 blockpos, std::string &data);
|
||||||
|
virtual std::string loadBlock(v3s16 blockpos);
|
||||||
|
virtual bool deleteBlock(v3s16 blockpos);
|
||||||
|
virtual void listAllLoadableBlocks(std::list<v3s16> &dst);
|
||||||
|
virtual int Initialized(void);
|
||||||
~Database_LevelDB();
|
~Database_LevelDB();
|
||||||
|
|
||||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data);
|
|
||||||
virtual std::string loadBlock(const v3s16 &pos);
|
|
||||||
virtual bool deleteBlock(const v3s16 &pos);
|
|
||||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
leveldb::DB *m_database;
|
ServerMap *srvmap;
|
||||||
|
leveldb::DB* m_database;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USE_LEVELDB
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -20,78 +20,84 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if USE_REDIS
|
#if USE_REDIS
|
||||||
|
/*
|
||||||
|
Redis databases
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "database-redis.h"
|
#include "database-redis.h"
|
||||||
|
#include <hiredis.h>
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
#include "mapsector.h"
|
||||||
|
#include "mapblock.h"
|
||||||
|
#include "serialization.h"
|
||||||
|
#include "main.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "exceptions.h"
|
#include "filesys.h"
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
#include <hiredis.h>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
|
|
||||||
Database_Redis::Database_Redis(Settings &conf)
|
Database_Redis::Database_Redis(ServerMap *map, std::string savedir)
|
||||||
{
|
{
|
||||||
|
Settings conf;
|
||||||
|
conf.readConfigFile((std::string(savedir) + DIR_DELIM + "world.mt").c_str());
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
try {
|
try {
|
||||||
tmp = conf.get("redis_address");
|
tmp = conf.get("redis_address");
|
||||||
hash = conf.get("redis_hash");
|
hash = conf.get("redis_hash");
|
||||||
} catch (SettingNotFoundException) {
|
} catch(SettingNotFoundException e) {
|
||||||
throw SettingNotFoundException("Set redis_address and "
|
throw SettingNotFoundException("Set redis_address and redis_hash in world.mt to use the redis backend");
|
||||||
"redis_hash in world.mt to use the redis backend");
|
|
||||||
}
|
}
|
||||||
const char *addr = tmp.c_str();
|
const char *addr = tmp.c_str();
|
||||||
int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379;
|
int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379;
|
||||||
ctx = redisConnect(addr, port);
|
ctx = redisConnect(addr, port);
|
||||||
if (!ctx) {
|
if(!ctx)
|
||||||
throw FileNotGoodException("Cannot allocate redis context");
|
throw FileNotGoodException("Cannot allocate redis context");
|
||||||
} else if(ctx->err) {
|
else if(ctx->err) {
|
||||||
std::string err = std::string("Connection error: ") + ctx->errstr;
|
std::string err = std::string("Connection error: ") + ctx->errstr;
|
||||||
redisFree(ctx);
|
redisFree(ctx);
|
||||||
throw FileNotGoodException(err);
|
throw FileNotGoodException(err);
|
||||||
}
|
}
|
||||||
|
srvmap = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database_Redis::~Database_Redis()
|
int Database_Redis::Initialized(void)
|
||||||
{
|
{
|
||||||
redisFree(ctx);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_Redis::beginSave() {
|
void Database_Redis::beginSave() {
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "MULTI"));
|
redisReply *reply;
|
||||||
if (!reply) {
|
reply = (redisReply*) redisCommand(ctx, "MULTI");
|
||||||
throw FileNotGoodException(std::string(
|
if(!reply)
|
||||||
"Redis command 'MULTI' failed: ") + ctx->errstr);
|
throw FileNotGoodException(std::string("redis command 'MULTI' failed: ") + ctx->errstr);
|
||||||
}
|
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_Redis::endSave() {
|
void Database_Redis::endSave() {
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "EXEC"));
|
redisReply *reply;
|
||||||
if (!reply) {
|
reply = (redisReply*) redisCommand(ctx, "EXEC");
|
||||||
throw FileNotGoodException(std::string(
|
if(!reply)
|
||||||
"Redis command 'EXEC' failed: ") + ctx->errstr);
|
throw FileNotGoodException(std::string("redis command 'EXEC' failed: ") + ctx->errstr);
|
||||||
}
|
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data)
|
bool Database_Redis::saveBlock(v3s16 blockpos, std::string &data)
|
||||||
{
|
{
|
||||||
std::string tmp = i64tos(getBlockAsInteger(pos));
|
std::string tmp = i64tos(getBlockAsInteger(blockpos));
|
||||||
|
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HSET %s %s %b",
|
redisReply *reply = (redisReply *)redisCommand(ctx, "HSET %s %s %b",
|
||||||
hash.c_str(), tmp.c_str(), data.c_str(), data.size()));
|
hash.c_str(), tmp.c_str(), data.c_str(), data.size());
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
errorstream << "WARNING: saveBlock: redis command 'HSET' failed on "
|
errorstream << "WARNING: saveBlock: redis command 'HSET' failed on "
|
||||||
"block " << PP(pos) << ": " << ctx->errstr << std::endl;
|
"block " << PP(blockpos) << ": " << ctx->errstr << std::endl;
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply->type == REDIS_REPLY_ERROR) {
|
if (reply->type == REDIS_REPLY_ERROR) {
|
||||||
errorstream << "WARNING: saveBlock: saving block " << PP(pos)
|
errorstream << "WARNING: saveBlock: saving block " << PP(blockpos)
|
||||||
<< "failed" << std::endl;
|
<< "failed" << std::endl;
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
return false;
|
return false;
|
||||||
|
@ -101,36 +107,38 @@ bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database_Redis::loadBlock(const v3s16 &pos)
|
std::string Database_Redis::loadBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
std::string tmp = i64tos(getBlockAsInteger(pos));
|
std::string tmp = i64tos(getBlockAsInteger(blockpos));
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx,
|
redisReply *reply;
|
||||||
"HGET %s %s", hash.c_str(), tmp.c_str()));
|
reply = (redisReply*) redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str());
|
||||||
|
|
||||||
if (!reply) {
|
if(!reply)
|
||||||
throw FileNotGoodException(std::string(
|
throw FileNotGoodException(std::string("redis command 'HGET %s %s' failed: ") + ctx->errstr);
|
||||||
"Redis command 'HGET %s %s' failed: ") + ctx->errstr);
|
if(reply->type != REDIS_REPLY_STRING)
|
||||||
} else if (reply->type != REDIS_REPLY_STRING) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
|
||||||
|
|
||||||
std::string str(reply->str, reply->len);
|
std::string str(reply->str, reply->len);
|
||||||
freeReplyObject(reply); // std::string copies the memory so this won't cause any problems
|
freeReplyObject(reply); // std::string copies the memory so this won't cause any problems
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_Redis::deleteBlock(const v3s16 &pos)
|
bool Database_Redis::deleteBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
std::string tmp = i64tos(getBlockAsInteger(pos));
|
std::string tmp = i64tos(getBlockAsInteger(blockpos));
|
||||||
|
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx,
|
redisReply *reply = (redisReply *)redisCommand(ctx, "HDEL %s %s",
|
||||||
"HDEL %s %s", hash.c_str(), tmp.c_str()));
|
hash.c_str(), tmp.c_str());
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
throw FileNotGoodException(std::string(
|
errorstream << "WARNING: deleteBlock: redis command 'HDEL' failed on "
|
||||||
"Redis command 'HDEL %s %s' failed: ") + ctx->errstr);
|
"block " << PP(blockpos) << ": " << ctx->errstr << std::endl;
|
||||||
} else if (reply->type == REDIS_REPLY_ERROR) {
|
freeReplyObject(reply);
|
||||||
errorstream << "WARNING: deleteBlock: deleting block " << PP(pos)
|
return false;
|
||||||
<< " failed" << std::endl;
|
}
|
||||||
|
|
||||||
|
if (reply->type == REDIS_REPLY_ERROR) {
|
||||||
|
errorstream << "WARNING: deleteBlock: deleting block " << PP(blockpos)
|
||||||
|
<< "failed" << std::endl;
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -139,21 +147,24 @@ bool Database_Redis::deleteBlock(const v3s16 &pos)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_Redis::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
void Database_Redis::listAllLoadableBlocks(std::list<v3s16> &dst)
|
||||||
{
|
{
|
||||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HKEYS %s", hash.c_str()));
|
redisReply *reply;
|
||||||
if (!reply) {
|
reply = (redisReply*) redisCommand(ctx, "HKEYS %s", hash.c_str());
|
||||||
throw FileNotGoodException(std::string(
|
if(!reply)
|
||||||
"Redis command 'HKEYS %s' failed: ") + ctx->errstr);
|
throw FileNotGoodException(std::string("redis command 'HKEYS %s' failed: ") + ctx->errstr);
|
||||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
if(reply->type != REDIS_REPLY_ARRAY)
|
||||||
throw FileNotGoodException("Failed to get keys from database");
|
throw FileNotGoodException("Failed to get keys from database");
|
||||||
}
|
for(size_t i = 0; i < reply->elements; i++)
|
||||||
for (size_t i = 0; i < reply->elements; i++) {
|
{
|
||||||
assert(reply->element[i]->type == REDIS_REPLY_STRING);
|
assert(reply->element[i]->type == REDIS_REPLY_STRING);
|
||||||
dst.push_back(getIntegerAsBlock(stoi64(reply->element[i]->str)));
|
dst.push_back(getIntegerAsBlock(stoi64(reply->element[i]->str)));
|
||||||
}
|
}
|
||||||
freeReplyObject(reply);
|
freeReplyObject(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_REDIS
|
Database_Redis::~Database_Redis()
|
||||||
|
{
|
||||||
|
redisFree(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -28,28 +28,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <hiredis.h>
|
#include <hiredis.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Settings;
|
class ServerMap;
|
||||||
|
|
||||||
class Database_Redis : public Database
|
class Database_Redis : public Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Database_Redis(Settings &conf);
|
Database_Redis(ServerMap *map, std::string savedir);
|
||||||
~Database_Redis();
|
|
||||||
|
|
||||||
virtual void beginSave();
|
virtual void beginSave();
|
||||||
virtual void endSave();
|
virtual void endSave();
|
||||||
|
virtual bool saveBlock(v3s16 blockpos, std::string &data);
|
||||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data);
|
virtual std::string loadBlock(v3s16 blockpos);
|
||||||
virtual std::string loadBlock(const v3s16 &pos);
|
virtual bool deleteBlock(v3s16 blockpos);
|
||||||
virtual bool deleteBlock(const v3s16 &pos);
|
virtual void listAllLoadableBlocks(std::list<v3s16> &dst);
|
||||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
virtual int Initialized(void);
|
||||||
|
~Database_Redis();
|
||||||
private:
|
private:
|
||||||
|
ServerMap *srvmap;
|
||||||
redisContext *ctx;
|
redisContext *ctx;
|
||||||
std::string hash;
|
std::string hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USE_REDIS
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -18,231 +18,297 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SQLite format specification:
|
SQLite format specification:
|
||||||
blocks:
|
- Initially only replaces sectors/ and sectors2/
|
||||||
(PK) INT id
|
|
||||||
BLOB data
|
If map.sqlite does not exist in the save dir
|
||||||
|
or the block was not found in the database
|
||||||
|
the map will try to load from sectors folder.
|
||||||
|
In either case, map.sqlite will be created
|
||||||
|
and all future saves will save there.
|
||||||
|
|
||||||
|
Structure of map.sqlite:
|
||||||
|
Tables:
|
||||||
|
blocks
|
||||||
|
(PK) INT pos
|
||||||
|
BLOB data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "database-sqlite3.h"
|
#include "database-sqlite3.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "map.h"
|
||||||
#include "filesys.h"
|
#include "mapsector.h"
|
||||||
#include "exceptions.h"
|
#include "mapblock.h"
|
||||||
|
#include "serialization.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "util/string.h"
|
#include "log.h"
|
||||||
|
#include "filesys.h"
|
||||||
|
|
||||||
#include <cassert>
|
Database_SQLite3::Database_SQLite3(ServerMap *map, std::string savedir)
|
||||||
|
|
||||||
|
|
||||||
#define SQLRES(s, r) \
|
|
||||||
if ((s) != (r)) { \
|
|
||||||
throw FileNotGoodException(std::string(\
|
|
||||||
"SQLite3 database error (" \
|
|
||||||
__FILE__ ":" TOSTRING(__LINE__) \
|
|
||||||
"): ") +\
|
|
||||||
sqlite3_errmsg(m_database)); \
|
|
||||||
}
|
|
||||||
#define SQLOK(s) SQLRES(s, SQLITE_OK)
|
|
||||||
|
|
||||||
#define PREPARE_STATEMENT(name, query) \
|
|
||||||
SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL))
|
|
||||||
|
|
||||||
#define FINALIZE_STATEMENT(statement) \
|
|
||||||
if (sqlite3_finalize(statement) != SQLITE_OK) { \
|
|
||||||
throw FileNotGoodException(std::string( \
|
|
||||||
"SQLite3: Failed to finalize " #statement ": ") + \
|
|
||||||
sqlite3_errmsg(m_database)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Database_SQLite3::Database_SQLite3(const std::string &savedir) :
|
|
||||||
m_initialized(false),
|
|
||||||
m_savedir(savedir),
|
|
||||||
m_database(NULL),
|
|
||||||
m_stmt_read(NULL),
|
|
||||||
m_stmt_write(NULL),
|
|
||||||
m_stmt_list(NULL),
|
|
||||||
m_stmt_delete(NULL)
|
|
||||||
{
|
{
|
||||||
|
m_database = NULL;
|
||||||
|
m_database_read = NULL;
|
||||||
|
m_database_write = NULL;
|
||||||
|
m_database_list = NULL;
|
||||||
|
m_database_delete = NULL;
|
||||||
|
m_savedir = savedir;
|
||||||
|
srvmap = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Database_SQLite3::Initialized(void)
|
||||||
|
{
|
||||||
|
return m_database ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::beginSave() {
|
void Database_SQLite3::beginSave() {
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE);
|
if(sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK)
|
||||||
sqlite3_reset(m_stmt_begin);
|
errorstream<<"WARNING: beginSave() failed, saving might be slow.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::endSave() {
|
void Database_SQLite3::endSave() {
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE);
|
if(sqlite3_exec(m_database, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK)
|
||||||
sqlite3_reset(m_stmt_end);
|
errorstream<<"WARNING: endSave() failed, map might not have saved.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::openDatabase()
|
void Database_SQLite3::createDirs(std::string path)
|
||||||
{
|
{
|
||||||
if (m_database) return;
|
if(fs::CreateAllDirs(path) == false)
|
||||||
|
{
|
||||||
|
infostream<<DTIME<<"Database_SQLite3: Failed to create directory "
|
||||||
|
<<"\""<<path<<"\""<<std::endl;
|
||||||
|
throw BaseException("Database_SQLite3 failed to create directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string dbp = m_savedir + DIR_DELIM + "map.sqlite";
|
void Database_SQLite3::verifyDatabase() {
|
||||||
|
if(m_database)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string dbp = m_savedir + DIR_DELIM "map.sqlite";
|
||||||
|
bool needs_create = false;
|
||||||
|
int d;
|
||||||
|
|
||||||
// Open the database connection
|
// Open the database connection
|
||||||
|
|
||||||
if (!fs::CreateAllDirs(m_savedir)) {
|
createDirs(m_savedir); // ?
|
||||||
infostream << "Database_SQLite3: Failed to create directory \""
|
|
||||||
<< m_savedir << "\"" << std::endl;
|
|
||||||
throw FileNotGoodException("Failed to create database "
|
|
||||||
"save directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needs_create = !fs::PathExists(dbp);
|
if(!fs::PathExists(dbp))
|
||||||
|
needs_create = true;
|
||||||
|
|
||||||
if (sqlite3_open_v2(dbp.c_str(), &m_database,
|
d = sqlite3_open_v2(dbp.c_str(), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
if(d != SQLITE_OK) {
|
||||||
NULL) != SQLITE_OK) {
|
errorstream<<"SQLite3 database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
errorstream << "SQLite3 database failed to open: "
|
|
||||||
<< sqlite3_errmsg(m_database) << std::endl;
|
|
||||||
throw FileNotGoodException("Cannot open database file");
|
throw FileNotGoodException("Cannot open database file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needs_create) {
|
if(needs_create)
|
||||||
createDatabase();
|
createDatabase();
|
||||||
}
|
|
||||||
|
|
||||||
std::string query_str = std::string("PRAGMA synchronous = ")
|
std::string querystr = std::string("PRAGMA synchronous = ")
|
||||||
+ itos(g_settings->getU16("sqlite_synchronous"));
|
+ itos(g_settings->getU16("sqlite_synchronous"));
|
||||||
SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL));
|
d = sqlite3_exec(m_database, querystr.c_str(), NULL, NULL, NULL);
|
||||||
}
|
if(d != SQLITE_OK) {
|
||||||
|
errorstream<<"Database pragma set failed: "
|
||||||
void Database_SQLite3::verifyDatabase()
|
<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
{
|
throw FileNotGoodException("Cannot set pragma");
|
||||||
if (m_initialized) return;
|
|
||||||
|
|
||||||
openDatabase();
|
|
||||||
|
|
||||||
PREPARE_STATEMENT(begin, "BEGIN");
|
|
||||||
PREPARE_STATEMENT(end, "COMMIT");
|
|
||||||
PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1");
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
PREPARE_STATEMENT(write, "INSERT INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
|
|
||||||
#else
|
|
||||||
PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
|
|
||||||
#endif
|
|
||||||
PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `pos` = ?");
|
|
||||||
PREPARE_STATEMENT(list, "SELECT `pos` FROM `blocks`");
|
|
||||||
|
|
||||||
m_initialized = true;
|
|
||||||
|
|
||||||
verbosestream << "ServerMap: SQLite3 database opened." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Database_SQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index)
|
|
||||||
{
|
|
||||||
SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos)));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database_SQLite3::deleteBlock(const v3s16 &pos)
|
|
||||||
{
|
|
||||||
verifyDatabase();
|
|
||||||
|
|
||||||
bindPos(m_stmt_delete, pos);
|
|
||||||
|
|
||||||
bool good = sqlite3_step(m_stmt_delete) == SQLITE_DONE;
|
|
||||||
sqlite3_reset(m_stmt_delete);
|
|
||||||
|
|
||||||
if (!good) {
|
|
||||||
errorstream << "WARNING: deleteBlock: Block failed to delete "
|
|
||||||
<< PP(pos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
|
||||||
}
|
}
|
||||||
return good;
|
|
||||||
|
d = sqlite3_prepare(m_database, "SELECT `data` FROM `blocks` WHERE `pos`=? LIMIT 1", -1, &m_database_read, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
errorstream<<"SQLite3 read statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare read statement");
|
||||||
|
}
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
d = sqlite3_prepare(m_database, "INSERT INTO `blocks` VALUES(?, ?);", -1, &m_database_write, NULL);
|
||||||
|
#else
|
||||||
|
d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?);", -1, &m_database_write, NULL);
|
||||||
|
#endif
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
errorstream<<"SQLite3 write statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare write statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
d = sqlite3_prepare(m_database, "DELETE FROM `blocks` WHERE `pos`=?;", -1, &m_database_delete, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
infostream<<"WARNING: SQLite3 database delete statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare delete statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
d = sqlite3_prepare(m_database, "SELECT `pos` FROM `blocks`", -1, &m_database_list, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
infostream<<"SQLite3 list statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare read statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
infostream<<"ServerMap: SQLite3 database opened"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database_SQLite3::saveBlock(const v3s16 &pos, const std::string &data)
|
bool Database_SQLite3::deleteBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
|
if (sqlite3_bind_int64(m_database_delete, 1,
|
||||||
|
getBlockAsInteger(blockpos)) != SQLITE_OK) {
|
||||||
|
errorstream << "WARNING: Could not bind block position for delete: "
|
||||||
|
<< sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_step(m_database_delete) != SQLITE_DONE) {
|
||||||
|
errorstream << "WARNING: deleteBlock: Block failed to delete "
|
||||||
|
<< PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
sqlite3_reset(m_database_delete);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_reset(m_database_delete);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database_SQLite3::saveBlock(v3s16 blockpos, std::string &data)
|
||||||
|
{
|
||||||
|
verifyDatabase();
|
||||||
|
|
||||||
|
s64 bkey = getBlockAsInteger(blockpos);
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
/**
|
/**
|
||||||
* Note: For some unknown reason SQLite3 fails to REPLACE blocks on Android,
|
* Note: For some unknown reason sqlite3 fails to REPLACE blocks on android,
|
||||||
* deleting them and then inserting works.
|
* deleting them and inserting first works.
|
||||||
*/
|
*/
|
||||||
bindPos(m_stmt_read, pos);
|
if (sqlite3_bind_int64(m_database_read, 1, bkey) != SQLITE_OK) {
|
||||||
|
infostream << "WARNING: Could not bind block position for load: "
|
||||||
if (sqlite3_step(m_stmt_read) == SQLITE_ROW) {
|
<< sqlite3_errmsg(m_database)<<std::endl;
|
||||||
deleteBlock(pos);
|
}
|
||||||
|
|
||||||
|
int step_result = sqlite3_step(m_database_read);
|
||||||
|
sqlite3_reset(m_database_read);
|
||||||
|
|
||||||
|
if (step_result == SQLITE_ROW) {
|
||||||
|
if (sqlite3_bind_int64(m_database_delete, 1, bkey) != SQLITE_OK) {
|
||||||
|
infostream << "WARNING: Could not bind block position for delete: "
|
||||||
|
<< sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_step(m_database_delete) != SQLITE_DONE) {
|
||||||
|
errorstream << "WARNING: saveBlock: Block failed to delete "
|
||||||
|
<< PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sqlite3_reset(m_database_delete);
|
||||||
}
|
}
|
||||||
sqlite3_reset(m_stmt_read);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bindPos(m_stmt_write, pos);
|
if (sqlite3_bind_int64(m_database_write, 1, bkey) != SQLITE_OK) {
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL));
|
errorstream << "WARNING: saveBlock: Block position failed to bind: "
|
||||||
|
<< PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
sqlite3_reset(m_database_write);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE)
|
if (sqlite3_bind_blob(m_database_write, 2, (void *)data.c_str(),
|
||||||
sqlite3_reset(m_stmt_write);
|
data.size(), NULL) != SQLITE_OK) {
|
||||||
|
errorstream << "WARNING: saveBlock: Block data failed to bind: "
|
||||||
|
<< PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
sqlite3_reset(m_database_write);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_step(m_database_write) != SQLITE_DONE) {
|
||||||
|
errorstream << "WARNING: saveBlock: Block failed to save "
|
||||||
|
<< PP(blockpos) << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
|
sqlite3_reset(m_database_write);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_reset(m_database_write);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database_SQLite3::loadBlock(const v3s16 &pos)
|
std::string Database_SQLite3::loadBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
bindPos(m_stmt_read, pos);
|
if (sqlite3_bind_int64(m_database_read, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) {
|
||||||
|
errorstream << "Could not bind block position for load: "
|
||||||
if (sqlite3_step(m_stmt_read) != SQLITE_ROW) {
|
<< sqlite3_errmsg(m_database)<<std::endl;
|
||||||
sqlite3_reset(m_stmt_read);
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
const char *data = (const char *) sqlite3_column_blob(m_stmt_read, 0);
|
|
||||||
size_t len = sqlite3_column_bytes(m_stmt_read, 0);
|
|
||||||
|
|
||||||
std::string s;
|
if (sqlite3_step(m_database_read) == SQLITE_ROW) {
|
||||||
if (data)
|
const char *data = (const char *) sqlite3_column_blob(m_database_read, 0);
|
||||||
s = std::string(data, len);
|
size_t len = sqlite3_column_bytes(m_database_read, 0);
|
||||||
|
|
||||||
sqlite3_step(m_stmt_read);
|
std::string s = "";
|
||||||
// We should never get more than 1 row, so ok to reset
|
if(data)
|
||||||
sqlite3_reset(m_stmt_read);
|
s = std::string(data, len);
|
||||||
|
|
||||||
return s;
|
sqlite3_step(m_database_read);
|
||||||
|
// We should never get more than 1 row, so ok to reset
|
||||||
|
sqlite3_reset(m_database_read);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_reset(m_database_read);
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::createDatabase()
|
void Database_SQLite3::createDatabase()
|
||||||
{
|
{
|
||||||
|
int e;
|
||||||
assert(m_database);
|
assert(m_database);
|
||||||
SQLOK(sqlite3_exec(m_database,
|
e = sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `blocks` (\n"
|
"CREATE TABLE IF NOT EXISTS `blocks` ("
|
||||||
" `pos` INT PRIMARY KEY,\n"
|
"`pos` INT NOT NULL PRIMARY KEY,"
|
||||||
" `data` BLOB\n"
|
"`data` BLOB"
|
||||||
");\n",
|
");"
|
||||||
NULL, NULL, NULL));
|
, NULL, NULL, NULL);
|
||||||
|
if(e != SQLITE_OK)
|
||||||
|
throw FileNotGoodException("Could not create sqlite3 database structure");
|
||||||
|
else
|
||||||
|
infostream<<"ServerMap: SQLite3 database structure was created";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
void Database_SQLite3::listAllLoadableBlocks(std::list<v3s16> &dst)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
while (sqlite3_step(m_stmt_list) == SQLITE_ROW) {
|
while(sqlite3_step(m_database_list) == SQLITE_ROW)
|
||||||
dst.push_back(getIntegerAsBlock(sqlite3_column_int64(m_stmt_list, 0)));
|
{
|
||||||
|
sqlite3_int64 block_i = sqlite3_column_int64(m_database_list, 0);
|
||||||
|
v3s16 p = getIntegerAsBlock(block_i);
|
||||||
|
//dstream<<"block_i="<<block_i<<" p="<<PP(p)<<std::endl;
|
||||||
|
dst.push_back(p);
|
||||||
}
|
}
|
||||||
sqlite3_reset(m_stmt_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FINALIZE_STATEMENT(statement) \
|
||||||
|
if ( statement ) \
|
||||||
|
rc = sqlite3_finalize(statement); \
|
||||||
|
if ( rc != SQLITE_OK ) \
|
||||||
|
errorstream << "Database_SQLite3::~Database_SQLite3():" \
|
||||||
|
<< "Failed to finalize: " << #statement << ": rc=" << rc << std::endl;
|
||||||
|
|
||||||
Database_SQLite3::~Database_SQLite3()
|
Database_SQLite3::~Database_SQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_read)
|
int rc = SQLITE_OK;
|
||||||
FINALIZE_STATEMENT(m_stmt_write)
|
|
||||||
FINALIZE_STATEMENT(m_stmt_list)
|
|
||||||
FINALIZE_STATEMENT(m_stmt_begin)
|
|
||||||
FINALIZE_STATEMENT(m_stmt_end)
|
|
||||||
FINALIZE_STATEMENT(m_stmt_delete)
|
|
||||||
|
|
||||||
if (sqlite3_close(m_database) != SQLITE_OK) {
|
FINALIZE_STATEMENT(m_database_read)
|
||||||
|
FINALIZE_STATEMENT(m_database_write)
|
||||||
|
FINALIZE_STATEMENT(m_database_list)
|
||||||
|
FINALIZE_STATEMENT(m_database_delete)
|
||||||
|
|
||||||
|
if(m_database)
|
||||||
|
rc = sqlite3_close(m_database);
|
||||||
|
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
errorstream << "Database_SQLite3::~Database_SQLite3(): "
|
errorstream << "Database_SQLite3::~Database_SQLite3(): "
|
||||||
<< "Failed to close database: "
|
<< "Failed to close database: rc=" << rc << std::endl;
|
||||||
<< sqlite3_errmsg(m_database) << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,43 +27,35 @@ extern "C" {
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ServerMap;
|
||||||
|
|
||||||
class Database_SQLite3 : public Database
|
class Database_SQLite3 : public Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Database_SQLite3(const std::string &savedir);
|
Database_SQLite3(ServerMap *map, std::string savedir);
|
||||||
|
|
||||||
virtual void beginSave();
|
virtual void beginSave();
|
||||||
virtual void endSave();
|
virtual void endSave();
|
||||||
|
|
||||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data);
|
virtual bool saveBlock(v3s16 blockpos, std::string &data);
|
||||||
virtual std::string loadBlock(const v3s16 &pos);
|
virtual std::string loadBlock(v3s16 blockpos);
|
||||||
virtual bool deleteBlock(const v3s16 &pos);
|
virtual bool deleteBlock(v3s16 blockpos);
|
||||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
virtual void listAllLoadableBlocks(std::list<v3s16> &dst);
|
||||||
virtual bool initialized() const { return m_initialized; }
|
virtual int Initialized(void);
|
||||||
~Database_SQLite3();
|
~Database_SQLite3();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Open the database
|
ServerMap *srvmap;
|
||||||
void openDatabase();
|
std::string m_savedir;
|
||||||
|
sqlite3 *m_database;
|
||||||
|
sqlite3_stmt *m_database_read;
|
||||||
|
sqlite3_stmt *m_database_write;
|
||||||
|
sqlite3_stmt *m_database_delete;
|
||||||
|
sqlite3_stmt *m_database_list;
|
||||||
|
|
||||||
// Create the database structure
|
// Create the database structure
|
||||||
void createDatabase();
|
void createDatabase();
|
||||||
// Open and initialize the database if needed
|
// Verify we can read/write to the database
|
||||||
void verifyDatabase();
|
void verifyDatabase();
|
||||||
|
void createDirs(std::string path);
|
||||||
void bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index=1);
|
|
||||||
|
|
||||||
bool m_initialized;
|
|
||||||
|
|
||||||
std::string m_savedir;
|
|
||||||
|
|
||||||
sqlite3 *m_database;
|
|
||||||
sqlite3_stmt *m_stmt_read;
|
|
||||||
sqlite3_stmt *m_stmt_write;
|
|
||||||
sqlite3_stmt *m_stmt_list;
|
|
||||||
sqlite3_stmt *m_stmt_delete;
|
|
||||||
sqlite3_stmt *m_stmt_begin;
|
|
||||||
sqlite3_stmt *m_stmt_end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ static inline s64 pythonmodulo(s64 i, s16 mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s64 Database::getBlockAsInteger(const v3s16 &pos)
|
s64 Database::getBlockAsInteger(const v3s16 pos) const
|
||||||
{
|
{
|
||||||
return (u64) pos.Z * 0x1000000 +
|
return (u64) pos.Z * 0x1000000 +
|
||||||
(u64) pos.Y * 0x1000 +
|
(u64) pos.Y * 0x1000 +
|
||||||
|
@ -56,7 +56,7 @@ s64 Database::getBlockAsInteger(const v3s16 &pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
v3s16 Database::getIntegerAsBlock(s64 i)
|
v3s16 Database::getIntegerAsBlock(s64 i) const
|
||||||
{
|
{
|
||||||
v3s16 pos;
|
v3s16 pos;
|
||||||
pos.X = unsigned_to_signed(pythonmodulo(i, 4096), 2048);
|
pos.X = unsigned_to_signed(pythonmodulo(i, 4096), 2048);
|
||||||
|
|
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#ifndef DATABASE_HEADER
|
#ifndef DATABASE_HEADER
|
||||||
#define DATABASE_HEADER
|
#define DATABASE_HEADER
|
||||||
|
|
||||||
#include <vector>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "irr_v3d.h"
|
#include "irr_v3d.h"
|
||||||
#include "irrlichttypes.h"
|
#include "irrlichttypes.h"
|
||||||
|
@ -32,22 +32,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Database() {}
|
virtual void beginSave() = 0;
|
||||||
|
virtual void endSave() = 0;
|
||||||
|
|
||||||
virtual void beginSave() {}
|
virtual bool saveBlock(v3s16 blockpos, std::string &data) = 0;
|
||||||
virtual void endSave() {}
|
virtual std::string loadBlock(v3s16 blockpos) = 0;
|
||||||
|
virtual bool deleteBlock(v3s16 blockpos) = 0;
|
||||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data) = 0;
|
s64 getBlockAsInteger(const v3s16 pos) const;
|
||||||
virtual std::string loadBlock(const v3s16 &pos) = 0;
|
v3s16 getIntegerAsBlock(s64 i) const;
|
||||||
virtual bool deleteBlock(const v3s16 &pos) = 0;
|
virtual void listAllLoadableBlocks(std::list<v3s16> &dst) = 0;
|
||||||
|
virtual int Initialized(void)=0;
|
||||||
static s64 getBlockAsInteger(const v3s16 &pos);
|
virtual ~Database() {};
|
||||||
static v3s16 getIntegerAsBlock(s64 i);
|
|
||||||
|
|
||||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst) = 0;
|
|
||||||
|
|
||||||
virtual bool initialized() const { return true; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("keymap_freemove", "KEY_KEY_K");
|
settings->setDefault("keymap_freemove", "KEY_KEY_K");
|
||||||
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
|
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
|
||||||
settings->setDefault("keymap_noclip", "KEY_KEY_H");
|
settings->setDefault("keymap_noclip", "KEY_KEY_H");
|
||||||
settings->setDefault("keymap_cinematic", "KEY_F8");
|
|
||||||
settings->setDefault("keymap_screenshot", "KEY_F12");
|
settings->setDefault("keymap_screenshot", "KEY_F12");
|
||||||
settings->setDefault("keymap_toggle_hud", "KEY_F1");
|
settings->setDefault("keymap_toggle_hud", "KEY_F1");
|
||||||
settings->setDefault("keymap_toggle_chat", "KEY_F2");
|
settings->setDefault("keymap_toggle_chat", "KEY_F2");
|
||||||
|
@ -116,9 +115,6 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("free_move", "false");
|
settings->setDefault("free_move", "false");
|
||||||
settings->setDefault("noclip", "false");
|
settings->setDefault("noclip", "false");
|
||||||
settings->setDefault("continuous_forward", "false");
|
settings->setDefault("continuous_forward", "false");
|
||||||
settings->setDefault("cinematic", "false");
|
|
||||||
settings->setDefault("camera_smoothing", "0");
|
|
||||||
settings->setDefault("cinematic_camera_smoothing", "0.7");
|
|
||||||
settings->setDefault("fast_move", "false");
|
settings->setDefault("fast_move", "false");
|
||||||
settings->setDefault("invert_mouse", "false");
|
settings->setDefault("invert_mouse", "false");
|
||||||
settings->setDefault("enable_clouds", "true");
|
settings->setDefault("enable_clouds", "true");
|
||||||
|
@ -292,7 +288,6 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("water_level", "1");
|
settings->setDefault("water_level", "1");
|
||||||
settings->setDefault("chunksize", "5");
|
settings->setDefault("chunksize", "5");
|
||||||
settings->setDefault("mg_flags", "");
|
settings->setDefault("mg_flags", "");
|
||||||
settings->setDefault("enable_floating_dungeons", "true");
|
|
||||||
|
|
||||||
// IPv6
|
// IPv6
|
||||||
settings->setDefault("enable_ipv6", "true");
|
settings->setDefault("enable_ipv6", "true");
|
||||||
|
|
|
@ -79,17 +79,14 @@ void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
|
||||||
// Dungeon generator doesn't modify places which have this set
|
// Dungeon generator doesn't modify places which have this set
|
||||||
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
||||||
|
|
||||||
bool no_float = !g_settings->getBool("enable_floating_dungeons");
|
// Set all air and water to be untouchable to make dungeons open
|
||||||
|
// to caves and open air
|
||||||
// Set all air and water (and optionally ignore) to be untouchable
|
|
||||||
// to make dungeons open to caves and open air
|
|
||||||
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
||||||
for (s16 y = nmin.Y; y <= nmax.Y; y++) {
|
for (s16 y = nmin.Y; y <= nmax.Y; y++) {
|
||||||
u32 i = vm->m_area.index(nmin.X, y, z);
|
u32 i = vm->m_area.index(nmin.X, y, z);
|
||||||
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
||||||
content_t c = vm->m_data[i].getContent();
|
content_t c = vm->m_data[i].getContent();
|
||||||
if (c == CONTENT_AIR || c == dp.c_water
|
if (c == CONTENT_AIR || c == dp.c_water)
|
||||||
|| (no_float && c == CONTENT_IGNORE))
|
|
||||||
vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
|
vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,10 +361,7 @@ void EmergeManager::loadParamsFromSettings(Settings *settings)
|
||||||
std::string seed_str;
|
std::string seed_str;
|
||||||
const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed";
|
const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed";
|
||||||
|
|
||||||
if (!settings->getNoEx("seed", seed_str)) {
|
if (settings->getNoEx(setname, seed_str) && !seed_str.empty()) {
|
||||||
g_settings->getNoEx(setname, seed_str);
|
|
||||||
}
|
|
||||||
if (!seed_str.empty()) {
|
|
||||||
params.seed = read_seed(seed_str.c_str());
|
params.seed = read_seed(seed_str.c_str());
|
||||||
} else {
|
} else {
|
||||||
params.seed =
|
params.seed =
|
||||||
|
|
|
@ -61,8 +61,9 @@ Environment::Environment():
|
||||||
Environment::~Environment()
|
Environment::~Environment()
|
||||||
{
|
{
|
||||||
// Deallocate players
|
// Deallocate players
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
delete (*i);
|
delete (*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +89,7 @@ void Environment::removePlayer(u16 peer_id)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end();)
|
i != m_players.end();)
|
||||||
{
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
|
@ -103,7 +104,7 @@ void Environment::removePlayer(u16 peer_id)
|
||||||
|
|
||||||
void Environment::removePlayer(const char *name)
|
void Environment::removePlayer(const char *name)
|
||||||
{
|
{
|
||||||
for (std::vector<Player*>::iterator it = m_players.begin();
|
for (std::list<Player*>::iterator it = m_players.begin();
|
||||||
it != m_players.end(); ++it) {
|
it != m_players.end(); ++it) {
|
||||||
if (strcmp((*it)->getName(), name) == 0) {
|
if (strcmp((*it)->getName(), name) == 0) {
|
||||||
delete *it;
|
delete *it;
|
||||||
|
@ -115,8 +116,9 @@ void Environment::removePlayer(const char *name)
|
||||||
|
|
||||||
Player * Environment::getPlayer(u16 peer_id)
|
Player * Environment::getPlayer(u16 peer_id)
|
||||||
{
|
{
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
if(player->peer_id == peer_id)
|
if(player->peer_id == peer_id)
|
||||||
return player;
|
return player;
|
||||||
|
@ -126,8 +128,9 @@ Player * Environment::getPlayer(u16 peer_id)
|
||||||
|
|
||||||
Player * Environment::getPlayer(const char *name)
|
Player * Environment::getPlayer(const char *name)
|
||||||
{
|
{
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
if(strcmp(player->getName(), name) == 0)
|
if(strcmp(player->getName(), name) == 0)
|
||||||
return player;
|
return player;
|
||||||
|
@ -137,13 +140,15 @@ Player * Environment::getPlayer(const char *name)
|
||||||
|
|
||||||
Player * Environment::getRandomConnectedPlayer()
|
Player * Environment::getRandomConnectedPlayer()
|
||||||
{
|
{
|
||||||
std::vector<Player*> connected_players = getPlayers(true);
|
std::list<Player*> connected_players = getPlayers(true);
|
||||||
u32 chosen_one = myrand() % connected_players.size();
|
u32 chosen_one = myrand() % connected_players.size();
|
||||||
u32 j = 0;
|
u32 j = 0;
|
||||||
for(std::vector<Player*>::iterator
|
for(std::list<Player*>::iterator
|
||||||
i = connected_players.begin();
|
i = connected_players.begin();
|
||||||
i != connected_players.end(); ++i) {
|
i != connected_players.end(); ++i)
|
||||||
if(j == chosen_one) {
|
{
|
||||||
|
if(j == chosen_one)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
@ -154,15 +159,17 @@ Player * Environment::getRandomConnectedPlayer()
|
||||||
|
|
||||||
Player * Environment::getNearestConnectedPlayer(v3f pos)
|
Player * Environment::getNearestConnectedPlayer(v3f pos)
|
||||||
{
|
{
|
||||||
std::vector<Player*> connected_players = getPlayers(true);
|
std::list<Player*> connected_players = getPlayers(true);
|
||||||
f32 nearest_d = 0;
|
f32 nearest_d = 0;
|
||||||
Player *nearest_player = NULL;
|
Player *nearest_player = NULL;
|
||||||
for(std::vector<Player*>::iterator
|
for(std::list<Player*>::iterator
|
||||||
i = connected_players.begin();
|
i = connected_players.begin();
|
||||||
i != connected_players.end(); ++i) {
|
i != connected_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
f32 d = player->getPosition().getDistanceFrom(pos);
|
f32 d = player->getPosition().getDistanceFrom(pos);
|
||||||
if(d < nearest_d || nearest_player == NULL) {
|
if(d < nearest_d || nearest_player == NULL)
|
||||||
|
{
|
||||||
nearest_d = d;
|
nearest_d = d;
|
||||||
nearest_player = player;
|
nearest_player = player;
|
||||||
}
|
}
|
||||||
|
@ -170,20 +177,22 @@ Player * Environment::getNearestConnectedPlayer(v3f pos)
|
||||||
return nearest_player;
|
return nearest_player;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Player*> Environment::getPlayers()
|
std::list<Player*> Environment::getPlayers()
|
||||||
{
|
{
|
||||||
return m_players;
|
return m_players;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Player*> Environment::getPlayers(bool ignore_disconnected)
|
std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
|
||||||
{
|
{
|
||||||
std::vector<Player*> newlist;
|
std::list<Player*> newlist;
|
||||||
for(std::vector<Player*>::iterator
|
for(std::list<Player*>::iterator
|
||||||
i = m_players.begin();
|
i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
|
|
||||||
if(ignore_disconnected) {
|
if(ignore_disconnected)
|
||||||
|
{
|
||||||
// Ignore disconnected players
|
// Ignore disconnected players
|
||||||
if(player->peer_id == 0)
|
if(player->peer_id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -203,42 +212,24 @@ u32 Environment::getDayNightRatio()
|
||||||
|
|
||||||
void Environment::setTimeOfDaySpeed(float speed)
|
void Environment::setTimeOfDaySpeed(float speed)
|
||||||
{
|
{
|
||||||
JMutexAutoLock(this->m_timeofday_lock);
|
JMutexAutoLock(this->m_lock);
|
||||||
m_time_of_day_speed = speed;
|
m_time_of_day_speed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Environment::getTimeOfDaySpeed()
|
float Environment::getTimeOfDaySpeed()
|
||||||
{
|
{
|
||||||
JMutexAutoLock(this->m_timeofday_lock);
|
JMutexAutoLock(this->m_lock);
|
||||||
float retval = m_time_of_day_speed;
|
float retval = m_time_of_day_speed;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::setTimeOfDay(u32 time)
|
|
||||||
{
|
|
||||||
JMutexAutoLock(this->m_time_lock);
|
|
||||||
m_time_of_day = time;
|
|
||||||
m_time_of_day_f = (float)time / 24000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 Environment::getTimeOfDay()
|
|
||||||
{
|
|
||||||
JMutexAutoLock(this->m_time_lock);
|
|
||||||
u32 retval = m_time_of_day;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Environment::getTimeOfDayF()
|
|
||||||
{
|
|
||||||
JMutexAutoLock(this->m_time_lock);
|
|
||||||
float retval = m_time_of_day_f;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Environment::stepTimeOfDay(float dtime)
|
void Environment::stepTimeOfDay(float dtime)
|
||||||
{
|
{
|
||||||
// getTimeOfDaySpeed lock the value we need to prevent MT problems
|
float day_speed = 0;
|
||||||
float day_speed = getTimeOfDaySpeed();
|
{
|
||||||
|
JMutexAutoLock(this->m_lock);
|
||||||
|
day_speed = m_time_of_day_speed;
|
||||||
|
}
|
||||||
|
|
||||||
m_time_counter += dtime;
|
m_time_counter += dtime;
|
||||||
f32 speed = day_speed * 24000./(24.*3600);
|
f32 speed = day_speed * 24000./(24.*3600);
|
||||||
|
@ -296,7 +287,7 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActiveBlockList::update(std::vector<v3s16> &active_positions,
|
void ActiveBlockList::update(std::list<v3s16> &active_positions,
|
||||||
s16 radius,
|
s16 radius,
|
||||||
std::set<v3s16> &blocks_removed,
|
std::set<v3s16> &blocks_removed,
|
||||||
std::set<v3s16> &blocks_added)
|
std::set<v3s16> &blocks_added)
|
||||||
|
@ -305,7 +296,7 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions,
|
||||||
Create the new list
|
Create the new list
|
||||||
*/
|
*/
|
||||||
std::set<v3s16> newlist = m_forceloaded_list;
|
std::set<v3s16> newlist = m_forceloaded_list;
|
||||||
for(std::vector<v3s16>::iterator i = active_positions.begin();
|
for(std::list<v3s16>::iterator i = active_positions.begin();
|
||||||
i != active_positions.end(); ++i)
|
i != active_positions.end(); ++i)
|
||||||
{
|
{
|
||||||
fillRadiusBlock(*i, radius, newlist);
|
fillRadiusBlock(*i, radius, newlist);
|
||||||
|
@ -382,7 +373,7 @@ ServerEnvironment::~ServerEnvironment()
|
||||||
m_map->drop();
|
m_map->drop();
|
||||||
|
|
||||||
// Delete ActiveBlockModifiers
|
// Delete ActiveBlockModifiers
|
||||||
for(std::vector<ABMWithState>::iterator
|
for(std::list<ABMWithState>::iterator
|
||||||
i = m_abms.begin(); i != m_abms.end(); ++i){
|
i = m_abms.begin(); i != m_abms.end(); ++i){
|
||||||
delete i->abm;
|
delete i->abm;
|
||||||
}
|
}
|
||||||
|
@ -404,8 +395,8 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
|
||||||
|
|
||||||
//calculate normalized direction vector
|
//calculate normalized direction vector
|
||||||
v3f normalized_vector = v3f((pos2.X - pos1.X)/distance,
|
v3f normalized_vector = v3f((pos2.X - pos1.X)/distance,
|
||||||
(pos2.Y - pos1.Y)/distance,
|
(pos2.Y - pos1.Y)/distance,
|
||||||
(pos2.Z - pos1.Z)/distance);
|
(pos2.Z - pos1.Z)/distance);
|
||||||
|
|
||||||
//find out if there's a node on path between pos1 and pos2
|
//find out if there's a node on path between pos1 and pos2
|
||||||
for (float i = 1; i < distance; i += stepsize) {
|
for (float i = 1; i < distance; i += stepsize) {
|
||||||
|
@ -430,7 +421,7 @@ void ServerEnvironment::saveLoadedPlayers()
|
||||||
std::string players_path = m_path_world + DIR_DELIM "players";
|
std::string players_path = m_path_world + DIR_DELIM "players";
|
||||||
fs::CreateDir(players_path);
|
fs::CreateDir(players_path);
|
||||||
|
|
||||||
for (std::vector<Player*>::iterator it = m_players.begin();
|
for (std::list<Player*>::iterator it = m_players.begin();
|
||||||
it != m_players.end();
|
it != m_players.end();
|
||||||
++it) {
|
++it) {
|
||||||
RemotePlayer *player = static_cast<RemotePlayer*>(*it);
|
RemotePlayer *player = static_cast<RemotePlayer*>(*it);
|
||||||
|
@ -558,9 +549,9 @@ class ABMHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ServerEnvironment *m_env;
|
ServerEnvironment *m_env;
|
||||||
std::map<content_t, std::vector<ActiveABM> > m_aabms;
|
std::map<content_t, std::list<ActiveABM> > m_aabms;
|
||||||
public:
|
public:
|
||||||
ABMHandler(std::vector<ABMWithState> &abms,
|
ABMHandler(std::list<ABMWithState> &abms,
|
||||||
float dtime_s, ServerEnvironment *env,
|
float dtime_s, ServerEnvironment *env,
|
||||||
bool use_timers):
|
bool use_timers):
|
||||||
m_env(env)
|
m_env(env)
|
||||||
|
@ -568,8 +559,8 @@ public:
|
||||||
if(dtime_s < 0.001)
|
if(dtime_s < 0.001)
|
||||||
return;
|
return;
|
||||||
INodeDefManager *ndef = env->getGameDef()->ndef();
|
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
for(std::vector<ABMWithState>::iterator
|
for(std::list<ABMWithState>::iterator
|
||||||
i = abms.begin(); i != abms.end(); ++i) {
|
i = abms.begin(); i != abms.end(); ++i){
|
||||||
ActiveBlockModifier *abm = i->abm;
|
ActiveBlockModifier *abm = i->abm;
|
||||||
float trigger_interval = abm->getTriggerInterval();
|
float trigger_interval = abm->getTriggerInterval();
|
||||||
if(trigger_interval < 0.001)
|
if(trigger_interval < 0.001)
|
||||||
|
@ -613,10 +604,10 @@ public:
|
||||||
k != ids.end(); k++)
|
k != ids.end(); k++)
|
||||||
{
|
{
|
||||||
content_t c = *k;
|
content_t c = *k;
|
||||||
std::map<content_t, std::vector<ActiveABM> >::iterator j;
|
std::map<content_t, std::list<ActiveABM> >::iterator j;
|
||||||
j = m_aabms.find(c);
|
j = m_aabms.find(c);
|
||||||
if(j == m_aabms.end()){
|
if(j == m_aabms.end()){
|
||||||
std::vector<ActiveABM> aabmlist;
|
std::list<ActiveABM> aabmlist;
|
||||||
m_aabms[c] = aabmlist;
|
m_aabms[c] = aabmlist;
|
||||||
j = m_aabms.find(c);
|
j = m_aabms.find(c);
|
||||||
}
|
}
|
||||||
|
@ -673,13 +664,14 @@ public:
|
||||||
content_t c = n.getContent();
|
content_t c = n.getContent();
|
||||||
v3s16 p = p0 + block->getPosRelative();
|
v3s16 p = p0 + block->getPosRelative();
|
||||||
|
|
||||||
std::map<content_t, std::vector<ActiveABM> >::iterator j;
|
std::map<content_t, std::list<ActiveABM> >::iterator j;
|
||||||
j = m_aabms.find(c);
|
j = m_aabms.find(c);
|
||||||
if(j == m_aabms.end())
|
if(j == m_aabms.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(std::vector<ActiveABM>::iterator
|
for(std::list<ActiveABM>::iterator
|
||||||
i = j->second.begin(); i != j->second.end(); i++) {
|
i = j->second.begin(); i != j->second.end(); i++)
|
||||||
|
{
|
||||||
if(myrand() % i->chance != 0)
|
if(myrand() % i->chance != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -859,10 +851,11 @@ void ServerEnvironment::clearAllObjects()
|
||||||
{
|
{
|
||||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||||
<<"Removing all active objects"<<std::endl;
|
<<"Removing all active objects"<<std::endl;
|
||||||
std::vector<u16> objects_to_remove;
|
std::list<u16> objects_to_remove;
|
||||||
for(std::map<u16, ServerActiveObject*>::iterator
|
for(std::map<u16, ServerActiveObject*>::iterator
|
||||||
i = m_active_objects.begin();
|
i = m_active_objects.begin();
|
||||||
i != m_active_objects.end(); ++i) {
|
i != m_active_objects.end(); ++i)
|
||||||
|
{
|
||||||
ServerActiveObject* obj = i->second;
|
ServerActiveObject* obj = i->second;
|
||||||
if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||||
continue;
|
continue;
|
||||||
|
@ -895,15 +888,15 @@ void ServerEnvironment::clearAllObjects()
|
||||||
// Id to be removed from m_active_objects
|
// Id to be removed from m_active_objects
|
||||||
objects_to_remove.push_back(id);
|
objects_to_remove.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove references from m_active_objects
|
// Remove references from m_active_objects
|
||||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||||
i != objects_to_remove.end(); ++i) {
|
i != objects_to_remove.end(); ++i)
|
||||||
|
{
|
||||||
m_active_objects.erase(*i);
|
m_active_objects.erase(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of loaded blocks
|
// Get list of loaded blocks
|
||||||
std::vector<v3s16> loaded_blocks;
|
std::list<v3s16> loaded_blocks;
|
||||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||||
<<"Listing all loaded blocks"<<std::endl;
|
<<"Listing all loaded blocks"<<std::endl;
|
||||||
m_map->listAllLoadedBlocks(loaded_blocks);
|
m_map->listAllLoadedBlocks(loaded_blocks);
|
||||||
|
@ -912,7 +905,7 @@ void ServerEnvironment::clearAllObjects()
|
||||||
<<loaded_blocks.size()<<std::endl;
|
<<loaded_blocks.size()<<std::endl;
|
||||||
|
|
||||||
// Get list of loadable blocks
|
// Get list of loadable blocks
|
||||||
std::vector<v3s16> loadable_blocks;
|
std::list<v3s16> loadable_blocks;
|
||||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||||
<<"Listing all loadable blocks"<<std::endl;
|
<<"Listing all loadable blocks"<<std::endl;
|
||||||
m_map->listAllLoadableBlocks(loadable_blocks);
|
m_map->listAllLoadableBlocks(loadable_blocks);
|
||||||
|
@ -922,8 +915,9 @@ void ServerEnvironment::clearAllObjects()
|
||||||
<<", now clearing"<<std::endl;
|
<<", now clearing"<<std::endl;
|
||||||
|
|
||||||
// Grab a reference on each loaded block to avoid unloading it
|
// Grab a reference on each loaded block to avoid unloading it
|
||||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
for(std::list<v3s16>::iterator i = loaded_blocks.begin();
|
||||||
i != loaded_blocks.end(); ++i) {
|
i != loaded_blocks.end(); ++i)
|
||||||
|
{
|
||||||
v3s16 p = *i;
|
v3s16 p = *i;
|
||||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||||
assert(block);
|
assert(block);
|
||||||
|
@ -937,8 +931,9 @@ void ServerEnvironment::clearAllObjects()
|
||||||
u32 num_blocks_checked = 0;
|
u32 num_blocks_checked = 0;
|
||||||
u32 num_blocks_cleared = 0;
|
u32 num_blocks_cleared = 0;
|
||||||
u32 num_objs_cleared = 0;
|
u32 num_objs_cleared = 0;
|
||||||
for(std::vector<v3s16>::iterator i = loadable_blocks.begin();
|
for(std::list<v3s16>::iterator i = loadable_blocks.begin();
|
||||||
i != loadable_blocks.end(); ++i) {
|
i != loadable_blocks.end(); ++i)
|
||||||
|
{
|
||||||
v3s16 p = *i;
|
v3s16 p = *i;
|
||||||
MapBlock *block = m_map->emergeBlock(p, false);
|
MapBlock *block = m_map->emergeBlock(p, false);
|
||||||
if(!block){
|
if(!block){
|
||||||
|
@ -974,8 +969,9 @@ void ServerEnvironment::clearAllObjects()
|
||||||
m_map->unloadUnreferencedBlocks();
|
m_map->unloadUnreferencedBlocks();
|
||||||
|
|
||||||
// Drop references that were added above
|
// Drop references that were added above
|
||||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
for(std::list<v3s16>::iterator i = loaded_blocks.begin();
|
||||||
i != loaded_blocks.end(); ++i) {
|
i != loaded_blocks.end(); ++i)
|
||||||
|
{
|
||||||
v3s16 p = *i;
|
v3s16 p = *i;
|
||||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||||
assert(block);
|
assert(block);
|
||||||
|
@ -1016,7 +1012,7 @@ void ServerEnvironment::step(float dtime)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG);
|
ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG);
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i)
|
i != m_players.end(); ++i)
|
||||||
{
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
|
@ -1039,15 +1035,15 @@ void ServerEnvironment::step(float dtime)
|
||||||
/*
|
/*
|
||||||
Get player block positions
|
Get player block positions
|
||||||
*/
|
*/
|
||||||
std::vector<v3s16> players_blockpos;
|
std::list<v3s16> players_blockpos;
|
||||||
for(std::vector<Player*>::iterator
|
for(std::list<Player*>::iterator
|
||||||
i = m_players.begin();
|
i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
// Ignore disconnected players
|
// Ignore disconnected players
|
||||||
if(player->peer_id == 0)
|
if(player->peer_id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
v3s16 blockpos = getNodeBlockPos(
|
v3s16 blockpos = getNodeBlockPos(
|
||||||
floatToInt(player->getPosition(), BS));
|
floatToInt(player->getPosition(), BS));
|
||||||
players_blockpos.push_back(blockpos);
|
players_blockpos.push_back(blockpos);
|
||||||
|
@ -1182,7 +1178,7 @@ void ServerEnvironment::step(float dtime)
|
||||||
<<") being handled"<<std::endl;*/
|
<<") being handled"<<std::endl;*/
|
||||||
|
|
||||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||||
if(block == NULL)
|
if(block==NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Set current time as timestamp
|
// Set current time as timestamp
|
||||||
|
@ -1239,8 +1235,7 @@ void ServerEnvironment::step(float dtime)
|
||||||
while(!obj->m_messages_out.empty())
|
while(!obj->m_messages_out.empty())
|
||||||
{
|
{
|
||||||
m_active_object_messages.push_back(
|
m_active_object_messages.push_back(
|
||||||
obj->m_messages_out.front());
|
obj->m_messages_out.pop_front());
|
||||||
obj->m_messages_out.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1547,10 +1542,11 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||||
*/
|
*/
|
||||||
void ServerEnvironment::removeRemovedObjects()
|
void ServerEnvironment::removeRemovedObjects()
|
||||||
{
|
{
|
||||||
std::vector<u16> objects_to_remove;
|
std::list<u16> objects_to_remove;
|
||||||
for(std::map<u16, ServerActiveObject*>::iterator
|
for(std::map<u16, ServerActiveObject*>::iterator
|
||||||
i = m_active_objects.begin();
|
i = m_active_objects.begin();
|
||||||
i != m_active_objects.end(); ++i) {
|
i != m_active_objects.end(); ++i)
|
||||||
|
{
|
||||||
u16 id = i->first;
|
u16 id = i->first;
|
||||||
ServerActiveObject* obj = i->second;
|
ServerActiveObject* obj = i->second;
|
||||||
// This shouldn't happen but check it
|
// This shouldn't happen but check it
|
||||||
|
@ -1620,13 +1616,13 @@ void ServerEnvironment::removeRemovedObjects()
|
||||||
// Delete
|
// Delete
|
||||||
if(obj->environmentDeletes())
|
if(obj->environmentDeletes())
|
||||||
delete obj;
|
delete obj;
|
||||||
|
|
||||||
// Id to be removed from m_active_objects
|
// Id to be removed from m_active_objects
|
||||||
objects_to_remove.push_back(id);
|
objects_to_remove.push_back(id);
|
||||||
}
|
}
|
||||||
// Remove references from m_active_objects
|
// Remove references from m_active_objects
|
||||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||||
i != objects_to_remove.end(); ++i) {
|
i != objects_to_remove.end(); ++i)
|
||||||
|
{
|
||||||
m_active_objects.erase(*i);
|
m_active_objects.erase(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1670,19 +1666,17 @@ static void print_hexdump(std::ostream &o, const std::string &data)
|
||||||
*/
|
*/
|
||||||
void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
||||||
{
|
{
|
||||||
if(block == NULL)
|
if(block==NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Ignore if no stored objects (to not set changed flag)
|
// Ignore if no stored objects (to not set changed flag)
|
||||||
if(block->m_static_objects.m_stored.empty())
|
if(block->m_static_objects.m_stored.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
verbosestream<<"ServerEnvironment::activateObjects(): "
|
verbosestream<<"ServerEnvironment::activateObjects(): "
|
||||||
<<"activating objects of block "<<PP(block->getPos())
|
<<"activating objects of block "<<PP(block->getPos())
|
||||||
<<" ("<<block->m_static_objects.m_stored.size()
|
<<" ("<<block->m_static_objects.m_stored.size()
|
||||||
<<" objects)"<<std::endl;
|
<<" objects)"<<std::endl;
|
||||||
bool large_amount = (block->m_static_objects.m_stored.size() > g_settings->getU16("max_objects_per_block"));
|
bool large_amount = (block->m_static_objects.m_stored.size() > g_settings->getU16("max_objects_per_block"));
|
||||||
if (large_amount) {
|
if(large_amount){
|
||||||
errorstream<<"suspiciously large amount of objects detected: "
|
errorstream<<"suspiciously large amount of objects detected: "
|
||||||
<<block->m_static_objects.m_stored.size()<<" in "
|
<<block->m_static_objects.m_stored.size()<<" in "
|
||||||
<<PP(block->getPos())
|
<<PP(block->getPos())
|
||||||
|
@ -1696,17 +1690,20 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate stored objects
|
// Activate stored objects
|
||||||
std::vector<StaticObject> new_stored;
|
std::list<StaticObject> new_stored;
|
||||||
for (std::vector<StaticObject>::iterator
|
for(std::list<StaticObject>::iterator
|
||||||
i = block->m_static_objects.m_stored.begin();
|
i = block->m_static_objects.m_stored.begin();
|
||||||
i != block->m_static_objects.m_stored.end(); ++i) {
|
i != block->m_static_objects.m_stored.end(); ++i)
|
||||||
|
{
|
||||||
|
/*infostream<<"Server: Creating an active object from "
|
||||||
|
<<"static data"<<std::endl;*/
|
||||||
StaticObject &s_obj = *i;
|
StaticObject &s_obj = *i;
|
||||||
|
|
||||||
// Create an active object from the data
|
// Create an active object from the data
|
||||||
ServerActiveObject *obj = ServerActiveObject::create
|
ServerActiveObject *obj = ServerActiveObject::create
|
||||||
((ActiveObjectType) s_obj.type, this, 0, s_obj.pos, s_obj.data);
|
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
|
||||||
// If couldn't create object, store static data back.
|
// If couldn't create object, store static data back.
|
||||||
if(obj == NULL) {
|
if(obj==NULL)
|
||||||
|
{
|
||||||
errorstream<<"ServerEnvironment::activateObjects(): "
|
errorstream<<"ServerEnvironment::activateObjects(): "
|
||||||
<<"failed to create active object from static object "
|
<<"failed to create active object from static object "
|
||||||
<<"in block "<<PP(s_obj.pos/BS)
|
<<"in block "<<PP(s_obj.pos/BS)
|
||||||
|
@ -1725,9 +1722,10 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
||||||
// Clear stored list
|
// Clear stored list
|
||||||
block->m_static_objects.m_stored.clear();
|
block->m_static_objects.m_stored.clear();
|
||||||
// Add leftover failed stuff to stored list
|
// Add leftover failed stuff to stored list
|
||||||
for(std::vector<StaticObject>::iterator
|
for(std::list<StaticObject>::iterator
|
||||||
i = new_stored.begin();
|
i = new_stored.begin();
|
||||||
i != new_stored.end(); ++i) {
|
i != new_stored.end(); ++i)
|
||||||
|
{
|
||||||
StaticObject &s_obj = *i;
|
StaticObject &s_obj = *i;
|
||||||
block->m_static_objects.m_stored.push_back(s_obj);
|
block->m_static_objects.m_stored.push_back(s_obj);
|
||||||
}
|
}
|
||||||
|
@ -1767,10 +1765,11 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
||||||
*/
|
*/
|
||||||
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||||
{
|
{
|
||||||
std::vector<u16> objects_to_remove;
|
std::list<u16> objects_to_remove;
|
||||||
for(std::map<u16, ServerActiveObject*>::iterator
|
for(std::map<u16, ServerActiveObject*>::iterator
|
||||||
i = m_active_objects.begin();
|
i = m_active_objects.begin();
|
||||||
i != m_active_objects.end(); ++i) {
|
i != m_active_objects.end(); ++i)
|
||||||
|
{
|
||||||
ServerActiveObject* obj = i->second;
|
ServerActiveObject* obj = i->second;
|
||||||
assert(obj);
|
assert(obj);
|
||||||
|
|
||||||
|
@ -1987,8 +1986,9 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove references from m_active_objects
|
// Remove references from m_active_objects
|
||||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||||
i != objects_to_remove.end(); ++i) {
|
i != objects_to_remove.end(); ++i)
|
||||||
|
{
|
||||||
m_active_objects.erase(*i);
|
m_active_objects.erase(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2025,8 +2025,9 @@ ClientEnvironment::~ClientEnvironment()
|
||||||
delete i->second;
|
delete i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<ClientSimpleObject*>::iterator
|
for(std::list<ClientSimpleObject*>::iterator
|
||||||
i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i) {
|
i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i)
|
||||||
|
{
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,8 +2059,9 @@ void ClientEnvironment::addPlayer(Player *player)
|
||||||
|
|
||||||
LocalPlayer * ClientEnvironment::getLocalPlayer()
|
LocalPlayer * ClientEnvironment::getLocalPlayer()
|
||||||
{
|
{
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
if(player->isLocal())
|
if(player->isLocal())
|
||||||
return (LocalPlayer*)player;
|
return (LocalPlayer*)player;
|
||||||
|
@ -2082,7 +2084,7 @@ void ClientEnvironment::step(float dtime)
|
||||||
LocalPlayer *lplayer = getLocalPlayer();
|
LocalPlayer *lplayer = getLocalPlayer();
|
||||||
assert(lplayer);
|
assert(lplayer);
|
||||||
// collision info queue
|
// collision info queue
|
||||||
std::vector<CollisionInfo> player_collisions;
|
std::list<CollisionInfo> player_collisions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the speed the player is going
|
Get the speed the player is going
|
||||||
|
@ -2197,8 +2199,10 @@ void ClientEnvironment::step(float dtime)
|
||||||
|
|
||||||
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
|
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
|
||||||
|
|
||||||
for(std::vector<CollisionInfo>::iterator i = player_collisions.begin();
|
for(std::list<CollisionInfo>::iterator
|
||||||
i != player_collisions.end(); ++i) {
|
i = player_collisions.begin();
|
||||||
|
i != player_collisions.end(); ++i)
|
||||||
|
{
|
||||||
CollisionInfo &info = *i;
|
CollisionInfo &info = *i;
|
||||||
v3f speed_diff = info.new_speed - info.old_speed;;
|
v3f speed_diff = info.new_speed - info.old_speed;;
|
||||||
// Handle only fall damage
|
// Handle only fall damage
|
||||||
|
@ -2313,14 +2317,16 @@ void ClientEnvironment::step(float dtime)
|
||||||
/*
|
/*
|
||||||
Stuff that can be done in an arbitarily large dtime
|
Stuff that can be done in an arbitarily large dtime
|
||||||
*/
|
*/
|
||||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
i != m_players.end(); ++i) {
|
i != m_players.end(); ++i)
|
||||||
|
{
|
||||||
Player *player = *i;
|
Player *player = *i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle non-local players
|
Handle non-local players
|
||||||
*/
|
*/
|
||||||
if(player->isLocal() == false) {
|
if(player->isLocal() == false)
|
||||||
|
{
|
||||||
// Move
|
// Move
|
||||||
player->move(dtime, this, 100*BS);
|
player->move(dtime, this, 100*BS);
|
||||||
|
|
||||||
|
@ -2381,18 +2387,16 @@ void ClientEnvironment::step(float dtime)
|
||||||
Step and handle simple objects
|
Step and handle simple objects
|
||||||
*/
|
*/
|
||||||
g_profiler->avg("CEnv: num of simple objects", m_simple_objects.size());
|
g_profiler->avg("CEnv: num of simple objects", m_simple_objects.size());
|
||||||
for(std::vector<ClientSimpleObject*>::iterator
|
for(std::list<ClientSimpleObject*>::iterator
|
||||||
i = m_simple_objects.begin(); i != m_simple_objects.end();) {
|
i = m_simple_objects.begin(); i != m_simple_objects.end();)
|
||||||
std::vector<ClientSimpleObject*>::iterator cur = i;
|
{
|
||||||
ClientSimpleObject *simple = *cur;
|
ClientSimpleObject *simple = *i;
|
||||||
|
std::list<ClientSimpleObject*>::iterator cur = i;
|
||||||
|
++i;
|
||||||
simple->step(dtime);
|
simple->step(dtime);
|
||||||
if(simple->m_to_be_removed) {
|
if(simple->m_to_be_removed){
|
||||||
delete simple;
|
delete simple;
|
||||||
i = m_simple_objects.erase(cur);
|
m_simple_objects.erase(cur);
|
||||||
}
|
|
||||||
else {
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2484,7 +2488,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
||||||
const std::string &init_data)
|
const std::string &init_data)
|
||||||
{
|
{
|
||||||
ClientActiveObject* obj =
|
ClientActiveObject* obj =
|
||||||
ClientActiveObject::create((ActiveObjectType) type, m_gamedef, this);
|
ClientActiveObject::create(type, m_gamedef, this);
|
||||||
if(obj == NULL)
|
if(obj == NULL)
|
||||||
{
|
{
|
||||||
infostream<<"ClientEnvironment::addActiveObject(): "
|
infostream<<"ClientEnvironment::addActiveObject(): "
|
||||||
|
|
|
@ -75,19 +75,28 @@ public:
|
||||||
Player * getPlayer(const char *name);
|
Player * getPlayer(const char *name);
|
||||||
Player * getRandomConnectedPlayer();
|
Player * getRandomConnectedPlayer();
|
||||||
Player * getNearestConnectedPlayer(v3f pos);
|
Player * getNearestConnectedPlayer(v3f pos);
|
||||||
std::vector<Player*> getPlayers();
|
std::list<Player*> getPlayers();
|
||||||
std::vector<Player*> getPlayers(bool ignore_disconnected);
|
std::list<Player*> getPlayers(bool ignore_disconnected);
|
||||||
|
|
||||||
u32 getDayNightRatio();
|
u32 getDayNightRatio();
|
||||||
|
|
||||||
// 0-23999
|
// 0-23999
|
||||||
virtual void setTimeOfDay(u32 time);
|
virtual void setTimeOfDay(u32 time)
|
||||||
u32 getTimeOfDay();
|
{
|
||||||
float getTimeOfDayF();
|
m_time_of_day = time;
|
||||||
|
m_time_of_day_f = (float)time / 24000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 getTimeOfDay()
|
||||||
|
{ return m_time_of_day; }
|
||||||
|
|
||||||
|
float getTimeOfDayF()
|
||||||
|
{ return m_time_of_day_f; }
|
||||||
|
|
||||||
void stepTimeOfDay(float dtime);
|
void stepTimeOfDay(float dtime);
|
||||||
|
|
||||||
void setTimeOfDaySpeed(float speed);
|
void setTimeOfDaySpeed(float speed);
|
||||||
|
|
||||||
float getTimeOfDaySpeed();
|
float getTimeOfDaySpeed();
|
||||||
|
|
||||||
void setDayNightRatioOverride(bool enable, u32 value)
|
void setDayNightRatioOverride(bool enable, u32 value)
|
||||||
|
@ -101,7 +110,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// peer_ids in here should be unique, except that there may be many 0s
|
// peer_ids in here should be unique, except that there may be many 0s
|
||||||
std::vector<Player*> m_players;
|
std::list<Player*> m_players;
|
||||||
// Time of day in milli-hours (0-23999); determines day and night
|
// Time of day in milli-hours (0-23999); determines day and night
|
||||||
u32 m_time_of_day;
|
u32 m_time_of_day;
|
||||||
// Time of day in 0...1
|
// Time of day in 0...1
|
||||||
|
@ -125,8 +134,7 @@ protected:
|
||||||
bool m_cache_enable_shaders;
|
bool m_cache_enable_shaders;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JMutex m_timeofday_lock;
|
JMutex m_lock;
|
||||||
JMutex m_time_lock;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,7 +182,7 @@ struct ABMWithState
|
||||||
class ActiveBlockList
|
class ActiveBlockList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void update(std::vector<v3s16> &active_positions,
|
void update(std::list<v3s16> &active_positions,
|
||||||
s16 radius,
|
s16 radius,
|
||||||
std::set<v3s16> &blocks_removed,
|
std::set<v3s16> &blocks_removed,
|
||||||
std::set<v3s16> &blocks_added);
|
std::set<v3s16> &blocks_added);
|
||||||
|
@ -393,7 +401,7 @@ private:
|
||||||
u32 m_game_time;
|
u32 m_game_time;
|
||||||
// A helper variable for incrementing the latter
|
// A helper variable for incrementing the latter
|
||||||
float m_game_time_fraction_counter;
|
float m_game_time_fraction_counter;
|
||||||
std::vector<ABMWithState> m_abms;
|
std::list<ABMWithState> m_abms;
|
||||||
// An interval for generally sending object positions and stuff
|
// An interval for generally sending object positions and stuff
|
||||||
float m_recommended_send_interval;
|
float m_recommended_send_interval;
|
||||||
// Estimate for general maximum lag as determined by server.
|
// Estimate for general maximum lag as determined by server.
|
||||||
|
@ -521,7 +529,7 @@ private:
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
IrrlichtDevice *m_irr;
|
IrrlichtDevice *m_irr;
|
||||||
std::map<u16, ClientActiveObject*> m_active_objects;
|
std::map<u16, ClientActiveObject*> m_active_objects;
|
||||||
std::vector<ClientSimpleObject*> m_simple_objects;
|
std::list<ClientSimpleObject*> m_simple_objects;
|
||||||
std::list<ClientEnvEvent> m_client_event_queue;
|
std::list<ClientEnvEvent> m_client_event_queue;
|
||||||
IntervalLimiter m_active_object_light_update_interval;
|
IntervalLimiter m_active_object_light_update_interval;
|
||||||
IntervalLimiter m_lava_hurt_interval;
|
IntervalLimiter m_lava_hurt_interval;
|
||||||
|
|
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "filecache.h"
|
#include "filecache.h"
|
||||||
|
|
||||||
#include "network/networkprotocol.h"
|
#include "clientserver.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
86
src/game.cpp
86
src/game.cpp
|
@ -51,7 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
#include "main.h" // For g_settings
|
#include "main.h" // For g_settings
|
||||||
#include "itemdef.h"
|
#include "itemdef.h"
|
||||||
#include "client/tile.h" // For TextureSource
|
#include "tile.h" // For TextureSource
|
||||||
#include "shader.h" // For ShaderSource
|
#include "shader.h" // For ShaderSource
|
||||||
#include "logoutputbuffer.h"
|
#include "logoutputbuffer.h"
|
||||||
#include "subgame.h"
|
#include "subgame.h"
|
||||||
|
@ -492,7 +492,7 @@ private:
|
||||||
color(color)
|
color(color)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
std::vector<Piece> m_log;
|
std::list<Piece> m_log;
|
||||||
public:
|
public:
|
||||||
u32 m_log_max_size;
|
u32 m_log_max_size;
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ public:
|
||||||
{
|
{
|
||||||
std::map<std::string, Meta> m_meta;
|
std::map<std::string, Meta> m_meta;
|
||||||
|
|
||||||
for (std::vector<Piece>::const_iterator k = m_log.begin();
|
for (std::list<Piece>::const_iterator k = m_log.begin();
|
||||||
k != m_log.end(); k++) {
|
k != m_log.end(); k++) {
|
||||||
const Piece &piece = *k;
|
const Piece &piece = *k;
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ public:
|
||||||
float lastscaledvalue = 0.0;
|
float lastscaledvalue = 0.0;
|
||||||
bool lastscaledvalue_exists = false;
|
bool lastscaledvalue_exists = false;
|
||||||
|
|
||||||
for (std::vector<Piece>::const_iterator j = m_log.begin();
|
for (std::list<Piece>::const_iterator j = m_log.begin();
|
||||||
j != m_log.end(); j++) {
|
j != m_log.end(); j++) {
|
||||||
const Piece &piece = *j;
|
const Piece &piece = *j;
|
||||||
float value = 0;
|
float value = 0;
|
||||||
|
@ -1043,11 +1043,7 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#define SIZE_TAG "size[11,5.5]"
|
#define SIZE_TAG "size[11,5.5]"
|
||||||
#else
|
|
||||||
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void show_chat_menu(GUIFormSpecMenu **cur_formspec,
|
static void show_chat_menu(GUIFormSpecMenu **cur_formspec,
|
||||||
InventoryManager *invmgr, IGameDef *gamedef,
|
InventoryManager *invmgr, IGameDef *gamedef,
|
||||||
|
@ -1078,7 +1074,7 @@ static void show_deathscreen(GUIFormSpecMenu **cur_formspec,
|
||||||
std::string(FORMSPEC_VERSION_STRING) +
|
std::string(FORMSPEC_VERSION_STRING) +
|
||||||
SIZE_TAG
|
SIZE_TAG
|
||||||
"bgcolor[#320000b4;true]"
|
"bgcolor[#320000b4;true]"
|
||||||
"label[4.85,1.35;" + gettext("You died.") + "]"
|
"label[4.85,1.35;You died.]"
|
||||||
"button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]"
|
"button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1137,7 +1133,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
|
||||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
||||||
<< wide_to_narrow(wstrgettext("Change Password")) << "]";
|
<< wide_to_narrow(wstrgettext("Change Password")) << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
|
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
|
||||||
<< wide_to_narrow(wstrgettext("Sound Volume")) << "]";
|
<< wide_to_narrow(wstrgettext("Sound Volume")) << "]";
|
||||||
|
@ -1161,7 +1157,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
|
||||||
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
|
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
|
||||||
|
|
||||||
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL);
|
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL);
|
||||||
(*cur_formspec)->setFocus(L"btn_continue");
|
|
||||||
(*cur_formspec)->doPause = true;
|
(*cur_formspec)->doPause = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,7 +1249,6 @@ struct KeyCache {
|
||||||
KEYMAP_ID_FREEMOVE,
|
KEYMAP_ID_FREEMOVE,
|
||||||
KEYMAP_ID_FASTMOVE,
|
KEYMAP_ID_FASTMOVE,
|
||||||
KEYMAP_ID_NOCLIP,
|
KEYMAP_ID_NOCLIP,
|
||||||
KEYMAP_ID_CINEMATIC,
|
|
||||||
KEYMAP_ID_SCREENSHOT,
|
KEYMAP_ID_SCREENSHOT,
|
||||||
KEYMAP_ID_TOGGLE_HUD,
|
KEYMAP_ID_TOGGLE_HUD,
|
||||||
KEYMAP_ID_TOGGLE_CHAT,
|
KEYMAP_ID_TOGGLE_CHAT,
|
||||||
|
@ -1302,7 +1297,6 @@ void KeyCache::populate()
|
||||||
key[KEYMAP_ID_FREEMOVE] = getKeySetting("keymap_freemove");
|
key[KEYMAP_ID_FREEMOVE] = getKeySetting("keymap_freemove");
|
||||||
key[KEYMAP_ID_FASTMOVE] = getKeySetting("keymap_fastmove");
|
key[KEYMAP_ID_FASTMOVE] = getKeySetting("keymap_fastmove");
|
||||||
key[KEYMAP_ID_NOCLIP] = getKeySetting("keymap_noclip");
|
key[KEYMAP_ID_NOCLIP] = getKeySetting("keymap_noclip");
|
||||||
key[KEYMAP_ID_CINEMATIC] = getKeySetting("keymap_cinematic");
|
|
||||||
key[KEYMAP_ID_SCREENSHOT] = getKeySetting("keymap_screenshot");
|
key[KEYMAP_ID_SCREENSHOT] = getKeySetting("keymap_screenshot");
|
||||||
key[KEYMAP_ID_TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
|
key[KEYMAP_ID_TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
|
||||||
key[KEYMAP_ID_TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
|
key[KEYMAP_ID_TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
|
||||||
|
@ -1499,7 +1493,6 @@ protected:
|
||||||
void toggleFreeMoveAlt(float *statustext_time, float *jump_timer);
|
void toggleFreeMoveAlt(float *statustext_time, float *jump_timer);
|
||||||
void toggleFast(float *statustext_time);
|
void toggleFast(float *statustext_time);
|
||||||
void toggleNoClip(float *statustext_time);
|
void toggleNoClip(float *statustext_time);
|
||||||
void toggleCinematic(float *statustext_time);
|
|
||||||
|
|
||||||
void toggleChat(float *statustext_time, bool *flag);
|
void toggleChat(float *statustext_time, bool *flag);
|
||||||
void toggleHud(float *statustext_time, bool *flag);
|
void toggleHud(float *statustext_time, bool *flag);
|
||||||
|
@ -1740,7 +1733,6 @@ void Game::run()
|
||||||
{
|
{
|
||||||
ProfilerGraph graph;
|
ProfilerGraph graph;
|
||||||
RunStats stats = { 0 };
|
RunStats stats = { 0 };
|
||||||
CameraOrientation cam_view_target = { 0 };
|
|
||||||
CameraOrientation cam_view = { 0 };
|
CameraOrientation cam_view = { 0 };
|
||||||
GameRunData runData = { 0 };
|
GameRunData runData = { 0 };
|
||||||
FpsControl draw_times = { 0 };
|
FpsControl draw_times = { 0 };
|
||||||
|
@ -1796,17 +1788,7 @@ void Game::run()
|
||||||
updateProfilers(runData, stats, draw_times, dtime);
|
updateProfilers(runData, stats, draw_times, dtime);
|
||||||
processUserInput(&flags, &runData, dtime);
|
processUserInput(&flags, &runData, dtime);
|
||||||
// Update camera before player movement to avoid camera lag of one frame
|
// Update camera before player movement to avoid camera lag of one frame
|
||||||
updateCameraDirection(&cam_view_target, &flags);
|
updateCameraDirection(&cam_view, &flags);
|
||||||
float cam_smoothing = 0;
|
|
||||||
if (g_settings->getBool("cinematic"))
|
|
||||||
cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing");
|
|
||||||
else
|
|
||||||
cam_smoothing = 1 - g_settings->getFloat("camera_smoothing");
|
|
||||||
cam_smoothing = rangelim(cam_smoothing, 0.01f, 1.0f);
|
|
||||||
cam_view.camera_yaw += (cam_view_target.camera_yaw -
|
|
||||||
cam_view.camera_yaw) * cam_smoothing;
|
|
||||||
cam_view.camera_pitch += (cam_view_target.camera_pitch -
|
|
||||||
cam_view.camera_pitch) * cam_smoothing;
|
|
||||||
updatePlayerControl(cam_view);
|
updatePlayerControl(cam_view);
|
||||||
step(&dtime);
|
step(&dtime);
|
||||||
processClientEvents(&cam_view, &runData.damage_flash);
|
processClientEvents(&cam_view, &runData.damage_flash);
|
||||||
|
@ -2582,8 +2564,6 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
|
||||||
toggleFast(statustext_time);
|
toggleFast(statustext_time);
|
||||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_NOCLIP])) {
|
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_NOCLIP])) {
|
||||||
toggleNoClip(statustext_time);
|
toggleNoClip(statustext_time);
|
||||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CINEMATIC])) {
|
|
||||||
toggleCinematic(statustext_time);
|
|
||||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_SCREENSHOT])) {
|
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_SCREENSHOT])) {
|
||||||
client->makeScreenshot(device);
|
client->makeScreenshot(device);
|
||||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
|
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
|
||||||
|
@ -2689,15 +2669,6 @@ void Game::dropSelectedItem()
|
||||||
|
|
||||||
void Game::openInventory()
|
void Game::openInventory()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Don't permit to open inventory is CAO or player doesn't exists.
|
|
||||||
* This prevent showing an empty inventory at player load
|
|
||||||
*/
|
|
||||||
|
|
||||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
|
||||||
if (player == NULL || player->getCAO() == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
infostream << "the_game: " << "Launching inventory" << std::endl;
|
infostream << "the_game: " << "Launching inventory" << std::endl;
|
||||||
|
|
||||||
PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client);
|
PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client);
|
||||||
|
@ -2770,16 +2741,6 @@ void Game::toggleNoClip(float *statustext_time)
|
||||||
statustext += L" (note: no 'noclip' privilege)";
|
statustext += L" (note: no 'noclip' privilege)";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::toggleCinematic(float *statustext_time)
|
|
||||||
{
|
|
||||||
static const wchar_t *msg[] = { L"cinematic disabled", L"cinematic enabled" };
|
|
||||||
bool cinematic = !g_settings->getBool("cinematic");
|
|
||||||
g_settings->set("cinematic", bool_to_cstr(cinematic));
|
|
||||||
|
|
||||||
*statustext_time = 0;
|
|
||||||
statustext = msg[cinematic];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Game::toggleChat(float *statustext_time, bool *flag)
|
void Game::toggleChat(float *statustext_time, bool *flag)
|
||||||
{
|
{
|
||||||
|
@ -3257,13 +3218,10 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time,
|
||||||
v3s16 old_camera_offset = camera->getOffset();
|
v3s16 old_camera_offset = camera->getOffset();
|
||||||
|
|
||||||
if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
|
if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
|
||||||
|
camera->toggleCameraMode();
|
||||||
GenericCAO *playercao = player->getCAO();
|
GenericCAO *playercao = player->getCAO();
|
||||||
|
|
||||||
// If playercao not loaded, don't change camera
|
assert(playercao != NULL);
|
||||||
if (playercao == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
camera->toggleCameraMode();
|
|
||||||
|
|
||||||
playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
||||||
}
|
}
|
||||||
|
@ -3968,28 +3926,6 @@ void Game::updateFrame(std::vector<aabb3f> &highlight_boxes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline static const char *yawToDirectionString(int yaw)
|
|
||||||
{
|
|
||||||
// NOTE: TODO: This can be done mathematically without the else/else-if
|
|
||||||
// cascade.
|
|
||||||
|
|
||||||
const char *player_direction;
|
|
||||||
|
|
||||||
yaw = wrapDegrees_0_360(yaw);
|
|
||||||
|
|
||||||
if (yaw >= 45 && yaw < 135)
|
|
||||||
player_direction = "West [-X]";
|
|
||||||
else if (yaw >= 135 && yaw < 225)
|
|
||||||
player_direction = "South [-Z]";
|
|
||||||
else if (yaw >= 225 && yaw < 315)
|
|
||||||
player_direction = "East [+X]";
|
|
||||||
else
|
|
||||||
player_direction = "North [+Z]";
|
|
||||||
|
|
||||||
return player_direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Game::updateGui(float *statustext_time, const RunStats &stats,
|
void Game::updateGui(float *statustext_time, const RunStats &stats,
|
||||||
const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
|
const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
|
||||||
const CameraOrientation &cam)
|
const CameraOrientation &cam)
|
||||||
|
@ -4045,7 +3981,6 @@ void Game::updateGui(float *statustext_time, const RunStats &stats,
|
||||||
<< ", " << (player_position.Y / BS)
|
<< ", " << (player_position.Y / BS)
|
||||||
<< ", " << (player_position.Z / BS)
|
<< ", " << (player_position.Z / BS)
|
||||||
<< ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw))
|
<< ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw))
|
||||||
<< " " << yawToDirectionString(cam.camera_yaw)
|
|
||||||
<< ") (seed = " << ((u64)client->getMapSeed())
|
<< ") (seed = " << ((u64)client->getMapSeed())
|
||||||
<< ")";
|
<< ")";
|
||||||
|
|
||||||
|
@ -4263,3 +4198,4 @@ void the_game(bool *kill,
|
||||||
error_message = narrow_to_wide(e.what()) + wstrgettext("\nCheck debug.txt for details.");
|
error_message = narrow_to_wide(e.what()) + wstrgettext("\nCheck debug.txt for details.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,24 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#if USE_GETTEXT && defined(_MSC_VER)
|
#if USE_GETTEXT && defined(_MSC_VER)
|
||||||
#include <windows.h>
|
#include <WinNls.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
|
|
||||||
#define setlocale(category, localename) \
|
#define setlocale(category,localename) \
|
||||||
setlocale(category, MSVC_LocaleLookup(localename))
|
setlocale(category,MSVC_LocaleLookup(localename))
|
||||||
|
|
||||||
static std::map<std::wstring, std::wstring> glb_supported_locales;
|
static std::map<std::wstring,std::wstring> glb_supported_locales;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||||
{
|
{
|
||||||
char* endptr = 0;
|
char* endptr = 0;
|
||||||
int LOCALEID = strtol(pStr, &endptr,16);
|
int LOCALEID = strtol(pStr,&endptr,16);
|
||||||
|
|
||||||
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
|
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer,0,sizeof(buffer));
|
||||||
if (GetLocaleInfoW(
|
if (GetLocaleInfoW(
|
||||||
LOCALEID,
|
LOCALEID,
|
||||||
LOCALE_SISO639LANGNAME,
|
LOCALE_SISO639LANGNAME,
|
||||||
|
@ -52,7 +52,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||||
|
|
||||||
std::wstring name = buffer;
|
std::wstring name = buffer;
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer,0,sizeof(buffer));
|
||||||
GetLocaleInfoW(
|
GetLocaleInfoW(
|
||||||
LOCALEID,
|
LOCALEID,
|
||||||
LOCALE_SISO3166CTRYNAME,
|
LOCALE_SISO3166CTRYNAME,
|
||||||
|
@ -61,7 +61,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||||
|
|
||||||
std::wstring country = buffer;
|
std::wstring country = buffer;
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer,0,sizeof(buffer));
|
||||||
GetLocaleInfoW(
|
GetLocaleInfoW(
|
||||||
LOCALEID,
|
LOCALEID,
|
||||||
LOCALE_SENGLISHLANGUAGENAME,
|
LOCALE_SENGLISHLANGUAGENAME,
|
||||||
|
@ -96,7 +96,7 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_use) {
|
if (first_use) {
|
||||||
EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
EnumSystemLocalesA(UpdateLocaleCallback,LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
||||||
first_use = false;
|
first_use = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +148,8 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||||
if (current_language_var != configured_language) {
|
if (current_language_var != configured_language) {
|
||||||
STARTUPINFO startupinfo;
|
STARTUPINFO startupinfo;
|
||||||
PROCESS_INFORMATION processinfo;
|
PROCESS_INFORMATION processinfo;
|
||||||
memset(&startupinfo, 0, sizeof(startupinfo));
|
memset(&startupinfo,0,sizeof(startupinfo));
|
||||||
memset(&processinfo, 0, sizeof(processinfo));
|
memset(&processinfo,0,sizeof(processinfo));
|
||||||
errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
|
errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
|
||||||
|
|
||||||
std::string parameters = "";
|
std::string parameters = "";
|
||||||
|
@ -169,7 +169,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||||
|
|
||||||
/** users may start by short name in commandline without extention **/
|
/** users may start by short name in commandline without extention **/
|
||||||
std::string appname = argv[0];
|
std::string appname = argv[0];
|
||||||
if (appname.substr(appname.length() - 4) != ".exe") {
|
if (appname.substr(appname.length() -4) != ".exe") {
|
||||||
appname += ".exe";
|
appname += ".exe";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||||
/* no matter what locale is used we need number format to be "C" */
|
/* no matter what locale is used we need number format to be "C" */
|
||||||
/* to ensure formspec parameters are evaluated correct! */
|
/* to ensure formspec parameters are evaluated correct! */
|
||||||
|
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC,"C");
|
||||||
infostream << "Message locale is now set to: "
|
infostream << "Message locale is now set to: "
|
||||||
<< setlocale(LC_ALL, 0) << std::endl;
|
<< setlocale(LC_ALL, 0) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,19 +41,16 @@ void init_gettext(const char *path, const std::string &configured_language);
|
||||||
extern const wchar_t *narrow_to_wide_c(const char *mbs);
|
extern const wchar_t *narrow_to_wide_c(const char *mbs);
|
||||||
extern std::wstring narrow_to_wide(const std::string &mbs);
|
extern std::wstring narrow_to_wide(const std::string &mbs);
|
||||||
|
|
||||||
|
|
||||||
// You must free the returned string!
|
// You must free the returned string!
|
||||||
inline const wchar_t *wgettext(const char *str)
|
inline const wchar_t *wgettext(const char *str)
|
||||||
{
|
{
|
||||||
return narrow_to_wide_c(gettext(str));
|
return narrow_to_wide_c(gettext(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gettext under MSVC needs this strange way. Just don't ask...
|
|
||||||
inline std::wstring wstrgettext(const std::string &text)
|
inline std::wstring wstrgettext(const std::string &text)
|
||||||
{
|
{
|
||||||
const wchar_t *tmp = wgettext(text.c_str());
|
return narrow_to_wide(gettext(text.c_str()));
|
||||||
std::wstring retval = (std::wstring)tmp;
|
|
||||||
delete[] tmp;
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string strgettext(const std::string &text)
|
inline std::string strgettext(const std::string &text)
|
||||||
|
|
|
@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "main.h" // for g_settings
|
#include "main.h" // for g_settings
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "fontengine.h"
|
#include "fontengine.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
@ -99,7 +99,7 @@ GUIChatConsole::GUIChatConsole(
|
||||||
{
|
{
|
||||||
core::dimension2d<u32> dim = m_font->getDimension(L"M");
|
core::dimension2d<u32> dim = m_font->getDimension(L"M");
|
||||||
m_fontsize = v2u32(dim.Width, dim.Height);
|
m_fontsize = v2u32(dim.Width, dim.Height);
|
||||||
m_font->grab();
|
dstream << "Font size: " << m_fontsize.X << " " << m_fontsize.Y << std::endl;
|
||||||
}
|
}
|
||||||
m_fontsize.X = MYMAX(m_fontsize.X, 1);
|
m_fontsize.X = MYMAX(m_fontsize.X, 1);
|
||||||
m_fontsize.Y = MYMAX(m_fontsize.Y, 1);
|
m_fontsize.Y = MYMAX(m_fontsize.Y, 1);
|
||||||
|
@ -109,10 +109,7 @@ GUIChatConsole::GUIChatConsole(
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIChatConsole::~GUIChatConsole()
|
GUIChatConsole::~GUIChatConsole()
|
||||||
{
|
{}
|
||||||
if (m_font)
|
|
||||||
m_font->drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GUIChatConsole::openConsole(f32 height)
|
void GUIChatConsole::openConsole(f32 height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,6 +122,9 @@ private:
|
||||||
// font
|
// font
|
||||||
gui::IGUIFont* m_font;
|
gui::IGUIFont* m_font;
|
||||||
v2u32 m_fontsize;
|
v2u32 m_fontsize;
|
||||||
|
#if USE_FREETYPE
|
||||||
|
bool m_use_freetype;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "fontengine.h"
|
#include "fontengine.h"
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "modalMenu.h"
|
#include "modalMenu.h"
|
||||||
#include "guiFormSpecMenu.h"
|
#include "guiFormSpecMenu.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Typedefs and macros */
|
/* Typedefs and macros */
|
||||||
|
|
|
@ -37,8 +37,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <IGUITabControl.h>
|
#include <IGUITabControl.h>
|
||||||
#include <IGUIComboBox.h>
|
#include <IGUIComboBox.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "client/tile.h" // ITextureSource
|
#include "tile.h" // ITextureSource
|
||||||
#include "hud.h" // drawItemStack
|
#include "hud.h" // drawItemStack
|
||||||
|
#include "hex.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "util/numeric.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
@ -47,10 +50,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "fontengine.h"
|
|
||||||
#include "util/hex.h"
|
|
||||||
#include "util/numeric.h"
|
|
||||||
#include "util/string.h" // for parseColorString()
|
#include "util/string.h" // for parseColorString()
|
||||||
|
#include "fontengine.h"
|
||||||
|
|
||||||
#define MY_CHECKPOS(a,b) \
|
#define MY_CHECKPOS(a,b) \
|
||||||
if (v_pos.size() != 2) { \
|
if (v_pos.size() != 2) { \
|
||||||
|
@ -96,7 +97,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
||||||
m_form_src(fsrc),
|
m_form_src(fsrc),
|
||||||
m_text_dst(tdst),
|
m_text_dst(tdst),
|
||||||
m_formspec_version(0),
|
m_formspec_version(0),
|
||||||
m_focused_element(L""),
|
|
||||||
m_font(NULL)
|
m_font(NULL)
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
,m_JavaDialogFieldName(L"")
|
,m_JavaDialogFieldName(L"")
|
||||||
|
@ -1757,6 +1757,8 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||||
{
|
{
|
||||||
/* useless to regenerate without a screensize */
|
/* useless to regenerate without a screensize */
|
||||||
|
@ -1773,10 +1775,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||||
mydata.table_dyndata[tablename] = table->getDynamicData();
|
mydata.table_dyndata[tablename] = table->getDynamicData();
|
||||||
}
|
}
|
||||||
|
|
||||||
//set focus
|
|
||||||
if (!m_focused_element.empty())
|
|
||||||
mydata.focused_fieldname = m_focused_element;
|
|
||||||
|
|
||||||
//preserve focus
|
//preserve focus
|
||||||
gui::IGUIElement *focused_element = Environment->getFocus();
|
gui::IGUIElement *focused_element = Environment->getFocus();
|
||||||
if (focused_element && focused_element->getParent() == this) {
|
if (focused_element && focused_element->getParent() == this) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "inventorymanager.h"
|
#include "inventorymanager.h"
|
||||||
#include "modalMenu.h"
|
#include "modalMenu.h"
|
||||||
#include "guiTable.h"
|
#include "guiTable.h"
|
||||||
#include "network/networkprotocol.h"
|
#include "clientserver.h"
|
||||||
|
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
class InventoryManager;
|
class InventoryManager;
|
||||||
|
@ -246,20 +246,13 @@ public:
|
||||||
m_allowclose = value;
|
m_allowclose = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0))
|
void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) {
|
||||||
{
|
|
||||||
m_lock = lock;
|
m_lock = lock;
|
||||||
m_lockscreensize = basescreensize;
|
m_lockscreensize = basescreensize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeChildren();
|
void removeChildren();
|
||||||
void setInitialFocus();
|
void setInitialFocus();
|
||||||
|
|
||||||
void setFocus(std::wstring elementname)
|
|
||||||
{
|
|
||||||
m_focused_element = elementname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove and re-add (or reposition) stuff
|
Remove and re-add (or reposition) stuff
|
||||||
*/
|
*/
|
||||||
|
@ -355,7 +348,6 @@ private:
|
||||||
IFormSource *m_form_src;
|
IFormSource *m_form_src;
|
||||||
TextDest *m_text_dst;
|
TextDest *m_text_dst;
|
||||||
unsigned int m_formspec_version;
|
unsigned int m_formspec_version;
|
||||||
std::wstring m_focused_element;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool explicit_size;
|
bool explicit_size;
|
||||||
|
|
|
@ -51,7 +51,6 @@ enum
|
||||||
GUI_ID_KEY_FAST_BUTTON,
|
GUI_ID_KEY_FAST_BUTTON,
|
||||||
GUI_ID_KEY_JUMP_BUTTON,
|
GUI_ID_KEY_JUMP_BUTTON,
|
||||||
GUI_ID_KEY_NOCLIP_BUTTON,
|
GUI_ID_KEY_NOCLIP_BUTTON,
|
||||||
GUI_ID_KEY_CINEMATIC_BUTTON,
|
|
||||||
GUI_ID_KEY_CHAT_BUTTON,
|
GUI_ID_KEY_CHAT_BUTTON,
|
||||||
GUI_ID_KEY_CMD_BUTTON,
|
GUI_ID_KEY_CMD_BUTTON,
|
||||||
GUI_ID_KEY_CONSOLE_BUTTON,
|
GUI_ID_KEY_CONSOLE_BUTTON,
|
||||||
|
@ -138,27 +137,27 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
||||||
{
|
{
|
||||||
key_setting *k = key_settings.at(i);
|
key_setting *k = key_settings.at(i);
|
||||||
{
|
{
|
||||||
core::rect < s32 > rect(0, 0, 110, 20);
|
core::rect < s32 > rect(0, 0, 100, 20);
|
||||||
rect += topleft + v2s32(offset.X, offset.Y);
|
rect += topleft + v2s32(offset.X, offset.Y);
|
||||||
Environment->addStaticText(k->button_name, rect, false, true, this, -1);
|
Environment->addStaticText(k->button_name, rect, false, true, this, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
core::rect < s32 > rect(0, 0, 100, 30);
|
core::rect < s32 > rect(0, 0, 100, 30);
|
||||||
rect += topleft + v2s32(offset.X + 115, offset.Y - 5);
|
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
|
||||||
const wchar_t *text = wgettext(k->key.name());
|
const wchar_t *text = wgettext(k->key.name());
|
||||||
k->button = Environment->addButton(rect, this, k->id, text);
|
k->button = Environment->addButton(rect, this, k->id, text);
|
||||||
delete[] text;
|
delete[] text;
|
||||||
}
|
}
|
||||||
if(i + 1 == KMaxButtonPerColumns)
|
if(i + 1 == KMaxButtonPerColumns)
|
||||||
offset = v2s32(260, 60);
|
offset = v2s32(250, 60);
|
||||||
else
|
else
|
||||||
offset += v2s32(0, 25);
|
offset += v2s32(0, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
s32 option_x = offset.X;
|
s32 option_x = offset.X + 10;
|
||||||
s32 option_y = offset.Y + 5;
|
s32 option_y = offset.Y;
|
||||||
u32 option_w = 180;
|
u32 option_w = 180;
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, option_w, 30);
|
core::rect<s32> rect(0, 0, option_w, 30);
|
||||||
|
@ -172,9 +171,9 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
s32 option_x = offset.X;
|
s32 option_x = offset.X + 10;
|
||||||
s32 option_y = offset.Y + 5;
|
s32 option_y = offset.Y;
|
||||||
u32 option_w = 280;
|
u32 option_w = 220;
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, option_w, 30);
|
core::rect<s32> rect(0, 0, option_w, 30);
|
||||||
rect += topleft + v2s32(option_x, option_y);
|
rect += topleft + v2s32(option_x, option_y);
|
||||||
|
@ -395,23 +394,22 @@ void GUIKeyChangeMenu::add_key(int id, const wchar_t *button_name, const std::st
|
||||||
|
|
||||||
void GUIKeyChangeMenu::init_keys()
|
void GUIKeyChangeMenu::init_keys()
|
||||||
{
|
{
|
||||||
this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
|
this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
|
||||||
this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward");
|
this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward");
|
||||||
this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left");
|
this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left");
|
||||||
this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
|
this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
|
||||||
this->add_key(GUI_ID_KEY_USE_BUTTON, wgettext("Use"), "keymap_special1");
|
this->add_key(GUI_ID_KEY_USE_BUTTON, wgettext("Use"), "keymap_special1");
|
||||||
this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
|
this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
|
||||||
this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
|
this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
|
||||||
this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
|
this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
|
||||||
this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
|
this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
|
||||||
this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
|
this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
|
||||||
this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd");
|
this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd");
|
||||||
this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console");
|
this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console");
|
||||||
this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove");
|
this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove");
|
||||||
this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove");
|
this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove");
|
||||||
this->add_key(GUI_ID_KEY_CINEMATIC_BUTTON, wgettext("Toggle Cinematic"), "keymap_cinematic");
|
this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip");
|
||||||
this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip");
|
this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
|
||||||
this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
|
this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");
|
||||||
this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||||
*/
|
*/
|
||||||
s32 ypos = 50;
|
s32 ypos = 50;
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 150, 20);
|
core::rect<s32> rect(0, 0, 110, 20);
|
||||||
rect += topleft_client + v2s32(25, ypos+6);
|
rect += topleft_client + v2s32(35, ypos+6);
|
||||||
text = wgettext("Old Password");
|
text = wgettext("Old Password");
|
||||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||||
delete[] text;
|
delete[] text;
|
||||||
|
@ -119,8 +119,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||||
}
|
}
|
||||||
ypos += 50;
|
ypos += 50;
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 150, 20);
|
core::rect<s32> rect(0, 0, 110, 20);
|
||||||
rect += topleft_client + v2s32(25, ypos+6);
|
rect += topleft_client + v2s32(35, ypos+6);
|
||||||
text = wgettext("New Password");
|
text = wgettext("New Password");
|
||||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||||
delete[] text;
|
delete[] text;
|
||||||
|
@ -134,8 +134,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||||
}
|
}
|
||||||
ypos += 50;
|
ypos += 50;
|
||||||
{
|
{
|
||||||
core::rect<s32> rect(0, 0, 150, 20);
|
core::rect<s32> rect(0, 0, 110, 20);
|
||||||
rect += topleft_client + v2s32(25, ypos+6);
|
rect += topleft_client + v2s32(35, ypos+6);
|
||||||
text = wgettext("Confirm Password");
|
text = wgettext("Confirm Password");
|
||||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||||
delete[] text;
|
delete[] text;
|
||||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <IGUIScrollBar.h>
|
#include <IGUIScrollBar.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
|
|
|
@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
JMutex g_httpfetch_mutex;
|
JMutex g_httpfetch_mutex;
|
||||||
std::map<unsigned long, std::queue<HTTPFetchResult> > g_httpfetch_results;
|
std::map<unsigned long, std::list<HTTPFetchResult> > g_httpfetch_results;
|
||||||
|
|
||||||
HTTPFetchRequest::HTTPFetchRequest()
|
HTTPFetchRequest::HTTPFetchRequest()
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ static void httpfetch_deliver_result(const HTTPFetchResult &fetch_result)
|
||||||
unsigned long caller = fetch_result.caller;
|
unsigned long caller = fetch_result.caller;
|
||||||
if (caller != HTTPFETCH_DISCARD) {
|
if (caller != HTTPFETCH_DISCARD) {
|
||||||
JMutexAutoLock lock(g_httpfetch_mutex);
|
JMutexAutoLock lock(g_httpfetch_mutex);
|
||||||
g_httpfetch_results[caller].push(fetch_result);
|
g_httpfetch_results[caller].push_back(fetch_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,11 +70,11 @@ unsigned long httpfetch_caller_alloc()
|
||||||
// Check each caller ID except HTTPFETCH_DISCARD
|
// Check each caller ID except HTTPFETCH_DISCARD
|
||||||
const unsigned long discard = HTTPFETCH_DISCARD;
|
const unsigned long discard = HTTPFETCH_DISCARD;
|
||||||
for (unsigned long caller = discard + 1; caller != discard; ++caller) {
|
for (unsigned long caller = discard + 1; caller != discard; ++caller) {
|
||||||
std::map<unsigned long, std::queue<HTTPFetchResult> >::iterator
|
std::map<unsigned long, std::list<HTTPFetchResult> >::iterator
|
||||||
it = g_httpfetch_results.find(caller);
|
it = g_httpfetch_results.find(caller);
|
||||||
if (it == g_httpfetch_results.end()) {
|
if (it == g_httpfetch_results.end()) {
|
||||||
verbosestream << "httpfetch_caller_alloc: allocating "
|
verbosestream<<"httpfetch_caller_alloc: allocating "
|
||||||
<< caller << std::endl;
|
<<caller<<std::endl;
|
||||||
// Access element to create it
|
// Access element to create it
|
||||||
g_httpfetch_results[caller];
|
g_httpfetch_results[caller];
|
||||||
return caller;
|
return caller;
|
||||||
|
@ -102,19 +102,19 @@ bool httpfetch_async_get(unsigned long caller, HTTPFetchResult &fetch_result)
|
||||||
JMutexAutoLock lock(g_httpfetch_mutex);
|
JMutexAutoLock lock(g_httpfetch_mutex);
|
||||||
|
|
||||||
// Check that caller exists
|
// Check that caller exists
|
||||||
std::map<unsigned long, std::queue<HTTPFetchResult> >::iterator
|
std::map<unsigned long, std::list<HTTPFetchResult> >::iterator
|
||||||
it = g_httpfetch_results.find(caller);
|
it = g_httpfetch_results.find(caller);
|
||||||
if (it == g_httpfetch_results.end())
|
if (it == g_httpfetch_results.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check that result queue is nonempty
|
// Check that result queue is nonempty
|
||||||
std::queue<HTTPFetchResult> &caller_results = it->second;
|
std::list<HTTPFetchResult> &caller_results = it->second;
|
||||||
if (caller_results.empty())
|
if (caller_results.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Pop first result
|
// Pop first result
|
||||||
fetch_result = caller_results.front();
|
fetch_result = caller_results.front();
|
||||||
caller_results.pop();
|
caller_results.pop_front();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +194,7 @@ private:
|
||||||
HTTPFetchRequest request;
|
HTTPFetchRequest request;
|
||||||
HTTPFetchResult result;
|
HTTPFetchResult result;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
char *post_fields;
|
||||||
struct curl_slist *http_header;
|
struct curl_slist *http_header;
|
||||||
curl_httppost *post;
|
curl_httppost *post;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "itemdef.h"
|
#include "itemdef.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "wieldmesh.h"
|
#include "wieldmesh.h"
|
||||||
#include "client/tile.h"
|
#include "tile.h"
|
||||||
#endif
|
#endif
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main.h" // g_settings
|
#include "main.h" // g_settings
|
||||||
|
@ -249,8 +249,8 @@ public:
|
||||||
virtual ~CItemDefManager()
|
virtual ~CItemDefManager()
|
||||||
{
|
{
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
const std::vector<ClientCached*> &values = m_clientcached.getValues();
|
const std::list<ClientCached*> &values = m_clientcached.getValues();
|
||||||
for(std::vector<ClientCached*>::const_iterator
|
for(std::list<ClientCached*>::const_iterator
|
||||||
i = values.begin(); i != values.end(); ++i)
|
i = values.begin(); i != values.end(); ++i)
|
||||||
{
|
{
|
||||||
ClientCached *cc = *i;
|
ClientCached *cc = *i;
|
||||||
|
@ -362,6 +362,8 @@ public:
|
||||||
|
|
||||||
scene::IMesh *node_mesh = NULL;
|
scene::IMesh *node_mesh = NULL;
|
||||||
|
|
||||||
|
bool reenable_shaders = false;
|
||||||
|
|
||||||
if (need_rtt_mesh || need_wield_mesh) {
|
if (need_rtt_mesh || need_wield_mesh) {
|
||||||
u8 param1 = 0;
|
u8 param1 = 0;
|
||||||
if (f.param_type == CPT_LIGHT)
|
if (f.param_type == CPT_LIGHT)
|
||||||
|
@ -370,7 +372,11 @@ public:
|
||||||
/*
|
/*
|
||||||
Make a mesh from the node
|
Make a mesh from the node
|
||||||
*/
|
*/
|
||||||
MeshMakeData mesh_make_data(gamedef, false);
|
if (g_settings->getBool("enable_shaders")) {
|
||||||
|
reenable_shaders = true;
|
||||||
|
g_settings->setBool("enable_shaders", false);
|
||||||
|
}
|
||||||
|
MeshMakeData mesh_make_data(gamedef);
|
||||||
u8 param2 = 0;
|
u8 param2 = 0;
|
||||||
if (f.param_type_2 == CPT2_WALLMOUNTED)
|
if (f.param_type_2 == CPT2_WALLMOUNTED)
|
||||||
param2 = 1;
|
param2 = 1;
|
||||||
|
@ -437,6 +443,9 @@ public:
|
||||||
|
|
||||||
if (node_mesh)
|
if (node_mesh)
|
||||||
node_mesh->drop();
|
node_mesh->drop();
|
||||||
|
|
||||||
|
if (reenable_shaders)
|
||||||
|
g_settings->setBool("enable_shaders",true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put in cache
|
// Put in cache
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif __MACH__
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#include <mach/task.h>
|
#include <mach/task.h>
|
||||||
#include <mach/semaphore.h>
|
#include <mach/semaphore.h>
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
class Event {
|
class Event {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE hEvent;
|
HANDLE hEvent;
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif __MACH__
|
||||||
semaphore_t sem;
|
semaphore_t sem;
|
||||||
#else
|
#else
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
|
|
|
@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define MAX_SEMAPHORE_COUNT 1024
|
#define MAX_SEMAPHORE_COUNT 1024
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif __MACH__
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#include <mach/task.h>
|
#include <mach/task.h>
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
private:
|
private:
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
HANDLE m_hSemaphore;
|
HANDLE m_hSemaphore;
|
||||||
#elif defined(__MACH__) && defined(__APPLE__)
|
#elif __MACH__
|
||||||
semaphore_t m_semaphore;
|
semaphore_t m_semaphore;
|
||||||
int semcount;
|
int semcount;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||||
|
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
#undef sem_t
|
#undef sem_t
|
||||||
#define sem_t semaphore_t
|
#define sem_t semaphore_t
|
||||||
#undef sem_init
|
#undef sem_init
|
||||||
|
|
|
@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "jthread/jsemaphore.h"
|
#include "jthread/jsemaphore.h"
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||||
|
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
#undef sem_t
|
#undef sem_t
|
||||||
#undef sem_init
|
#undef sem_init
|
||||||
#undef sem_wait
|
#undef sem_wait
|
||||||
|
@ -44,7 +44,7 @@ JSemaphore::JSemaphore() {
|
||||||
int sem_init_retval = sem_init(&m_semaphore,0,0);
|
int sem_init_retval = sem_init(&m_semaphore,0,0);
|
||||||
assert(sem_init_retval == 0);
|
assert(sem_init_retval == 0);
|
||||||
UNUSED(sem_init_retval);
|
UNUSED(sem_init_retval);
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
semcount = 0;
|
semcount = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ void JSemaphore::Post() {
|
||||||
int sem_post_retval = sem_post(&m_semaphore);
|
int sem_post_retval = sem_post(&m_semaphore);
|
||||||
assert(sem_post_retval == 0);
|
assert(sem_post_retval == 0);
|
||||||
UNUSED(sem_post_retval);
|
UNUSED(sem_post_retval);
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
pthread_mutex_lock(&semcount_mutex);
|
pthread_mutex_lock(&semcount_mutex);
|
||||||
semcount++;
|
semcount++;
|
||||||
pthread_mutex_unlock(&semcount_mutex);
|
pthread_mutex_unlock(&semcount_mutex);
|
||||||
|
@ -84,7 +84,7 @@ void JSemaphore::Wait() {
|
||||||
int sem_wait_retval = sem_wait(&m_semaphore);
|
int sem_wait_retval = sem_wait(&m_semaphore);
|
||||||
assert(sem_wait_retval == 0);
|
assert(sem_wait_retval == 0);
|
||||||
UNUSED(sem_wait_retval);
|
UNUSED(sem_wait_retval);
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
pthread_mutex_lock(&semcount_mutex);
|
pthread_mutex_lock(&semcount_mutex);
|
||||||
semcount--;
|
semcount--;
|
||||||
pthread_mutex_unlock(&semcount_mutex);
|
pthread_mutex_unlock(&semcount_mutex);
|
||||||
|
@ -92,7 +92,7 @@ void JSemaphore::Wait() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JSemaphore::Wait(unsigned int time_ms) {
|
bool JSemaphore::Wait(unsigned int time_ms) {
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
mach_timespec_t waittime;
|
mach_timespec_t waittime;
|
||||||
waittime.tv_sec = time_ms / 1000;
|
waittime.tv_sec = time_ms / 1000;
|
||||||
waittime.tv_nsec = 1000000 * (time_ms % 1000);
|
waittime.tv_nsec = 1000000 * (time_ms % 1000);
|
||||||
|
@ -106,14 +106,14 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !(defined(__MACH__) && defined(__APPLE__))
|
#ifndef __MACH__
|
||||||
waittime.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
|
waittime.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
|
||||||
waittime.tv_sec = (time_ms / 1000) + (waittime.tv_nsec / (1000*1000*1000)) + now.tv_sec;
|
waittime.tv_sec = (time_ms / 1000) + (waittime.tv_nsec / (1000*1000*1000)) + now.tv_sec;
|
||||||
waittime.tv_nsec %= 1000*1000*1000;
|
waittime.tv_nsec %= 1000*1000*1000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
int sem_wait_retval = semaphore_timedwait(m_semaphore, waittime);
|
int sem_wait_retval = semaphore_timedwait(m_semaphore, waittime);
|
||||||
if (sem_wait_retval == KERN_OPERATION_TIMED_OUT) {
|
if (sem_wait_retval == KERN_OPERATION_TIMED_OUT) {
|
||||||
errno = ETIMEDOUT;
|
errno = ETIMEDOUT;
|
||||||
|
@ -128,7 +128,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||||
|
|
||||||
if (sem_wait_retval == 0)
|
if (sem_wait_retval == 0)
|
||||||
{
|
{
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
pthread_mutex_lock(&semcount_mutex);
|
pthread_mutex_lock(&semcount_mutex);
|
||||||
semcount--;
|
semcount--;
|
||||||
pthread_mutex_unlock(&semcount_mutex);
|
pthread_mutex_unlock(&semcount_mutex);
|
||||||
|
@ -144,7 +144,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||||
|
|
||||||
int JSemaphore::GetValue() {
|
int JSemaphore::GetValue() {
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
#ifdef __MACH__
|
||||||
pthread_mutex_lock(&semcount_mutex);
|
pthread_mutex_lock(&semcount_mutex);
|
||||||
retval = semcount;
|
retval = semcount;
|
||||||
pthread_mutex_unlock(&semcount_mutex);
|
pthread_mutex_unlock(&semcount_mutex);
|
||||||
|
|
|
@ -22,8 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "hex.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "util/hex.h"
|
|
||||||
|
|
||||||
class UnknownKeycode : public BaseException
|
class UnknownKeycode : public BaseException
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,7 @@ LocalPlayer::~LocalPlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||||
std::vector<CollisionInfo> *collision_info)
|
std::list<CollisionInfo> *collision_info)
|
||||||
{
|
{
|
||||||
Map *map = &env->getMap();
|
Map *map = &env->getMap();
|
||||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||||
|
@ -323,8 +323,9 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||||
*/
|
*/
|
||||||
bool bouncy_jump = false;
|
bool bouncy_jump = false;
|
||||||
// Dont report if flying
|
// Dont report if flying
|
||||||
if(collision_info && !(g_settings->getBool("free_move") && fly_allowed)) {
|
if(collision_info && !(g_settings->getBool("free_move") && fly_allowed))
|
||||||
for(size_t i=0; i<result.collisions.size(); i++) {
|
{
|
||||||
|
for(size_t i=0; i<result.collisions.size(); i++){
|
||||||
const CollisionInfo &info = result.collisions[i];
|
const CollisionInfo &info = result.collisions[i];
|
||||||
collision_info->push_back(info);
|
collision_info->push_back(info);
|
||||||
if(info.new_speed.Y - info.old_speed.Y > 0.1*BS &&
|
if(info.new_speed.Y - info.old_speed.Y > 0.1*BS &&
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
|
|
||||||
void move(f32 dtime, Environment *env, f32 pos_max_d);
|
void move(f32 dtime, Environment *env, f32 pos_max_d);
|
||||||
void move(f32 dtime, Environment *env, f32 pos_max_d,
|
void move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||||
std::vector<CollisionInfo> *collision_info);
|
std::list<CollisionInfo> *collision_info);
|
||||||
|
|
||||||
void applyControl(float dtime);
|
void applyControl(float dtime);
|
||||||
|
|
||||||
|
|
35
src/log.cpp
35
src/log.cpp
|
@ -24,14 +24,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "jthread/jmutexautolock.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
unsigned int android_log_level_mapping[] = {
|
unsigned int android_log_level_mapping[] {
|
||||||
/* LMT_ERROR */ ANDROID_LOG_ERROR,
|
/* LMT_ERROR */ ANDROID_LOG_ERROR,
|
||||||
/* LMT_ACTION */ ANDROID_LOG_WARN,
|
/* LMT_ACTION */ ANDROID_LOG_WARN,
|
||||||
/* LMT_INFO */ ANDROID_LOG_INFO,
|
/* LMT_INFO */ ANDROID_LOG_INFO,
|
||||||
|
@ -39,7 +38,7 @@ unsigned int android_log_level_mapping[] = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<ILogOutput*> log_outputs[LMT_NUM_VALUES];
|
std::list<ILogOutput*> log_outputs[LMT_NUM_VALUES];
|
||||||
std::map<threadid_t, std::string> log_threadnames;
|
std::map<threadid_t, std::string> log_threadnames;
|
||||||
JMutex log_threadnamemutex;
|
JMutex log_threadnamemutex;
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ void log_add_output_all_levs(ILogOutput *out)
|
||||||
void log_remove_output(ILogOutput *out)
|
void log_remove_output(ILogOutput *out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<LMT_NUM_VALUES; i++){
|
for(int i=0; i<LMT_NUM_VALUES; i++){
|
||||||
std::vector<ILogOutput*>::iterator it =
|
std::list<ILogOutput*>::iterator it =
|
||||||
std::find(log_outputs[i].begin(), log_outputs[i].end(), out);
|
std::find(log_outputs[i].begin(), log_outputs[i].end(), out);
|
||||||
if(it != log_outputs[i].end())
|
if(it != log_outputs[i].end())
|
||||||
log_outputs[i].erase(it);
|
log_outputs[i].erase(it);
|
||||||
|
@ -72,29 +71,33 @@ void log_remove_output(ILogOutput *out)
|
||||||
|
|
||||||
void log_set_lev_silence(enum LogMessageLevel lev, bool silence)
|
void log_set_lev_silence(enum LogMessageLevel lev, bool silence)
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(log_threadnamemutex);
|
log_threadnamemutex.Lock();
|
||||||
|
|
||||||
for (std::vector<ILogOutput *>::iterator it = log_outputs[lev].begin();
|
for (std::list<ILogOutput *>::iterator
|
||||||
it != log_outputs[lev].end(); ++it) {
|
it = log_outputs[lev].begin();
|
||||||
|
it != log_outputs[lev].end();
|
||||||
|
++it) {
|
||||||
ILogOutput *out = *it;
|
ILogOutput *out = *it;
|
||||||
out->silence = silence;
|
out->silence = silence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_threadnamemutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_register_thread(const std::string &name)
|
void log_register_thread(const std::string &name)
|
||||||
{
|
{
|
||||||
threadid_t id = get_current_thread_id();
|
threadid_t id = get_current_thread_id();
|
||||||
JMutexAutoLock lock(log_threadnamemutex);
|
log_threadnamemutex.Lock();
|
||||||
|
|
||||||
log_threadnames[id] = name;
|
log_threadnames[id] = name;
|
||||||
|
log_threadnamemutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_deregister_thread()
|
void log_deregister_thread()
|
||||||
{
|
{
|
||||||
threadid_t id = get_current_thread_id();
|
threadid_t id = get_current_thread_id();
|
||||||
JMutexAutoLock lock(log_threadnamemutex);
|
log_threadnamemutex.Lock();
|
||||||
|
|
||||||
log_threadnames.erase(id);
|
log_threadnames.erase(id);
|
||||||
|
log_threadnamemutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string get_lev_string(enum LogMessageLevel lev)
|
static std::string get_lev_string(enum LogMessageLevel lev)
|
||||||
|
@ -116,7 +119,7 @@ static std::string get_lev_string(enum LogMessageLevel lev)
|
||||||
|
|
||||||
void log_printline(enum LogMessageLevel lev, const std::string &text)
|
void log_printline(enum LogMessageLevel lev, const std::string &text)
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(log_threadnamemutex);
|
log_threadnamemutex.Lock();
|
||||||
std::string threadname = "(unknown thread)";
|
std::string threadname = "(unknown thread)";
|
||||||
std::map<threadid_t, std::string>::const_iterator i;
|
std::map<threadid_t, std::string>::const_iterator i;
|
||||||
i = log_threadnames.find(get_current_thread_id());
|
i = log_threadnames.find(get_current_thread_id());
|
||||||
|
@ -124,10 +127,9 @@ void log_printline(enum LogMessageLevel lev, const std::string &text)
|
||||||
threadname = i->second;
|
threadname = i->second;
|
||||||
std::string levelname = get_lev_string(lev);
|
std::string levelname = get_lev_string(lev);
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
os << getTimestamp() << ": " << levelname << "["<<threadname<<"]: " << text;
|
os<<getTimestamp()<<": "<<levelname<<"["<<threadname<<"]: "<<text;
|
||||||
|
for(std::list<ILogOutput*>::iterator i = log_outputs[lev].begin();
|
||||||
for(std::vector<ILogOutput*>::iterator i = log_outputs[lev].begin();
|
i != log_outputs[lev].end(); i++){
|
||||||
i != log_outputs[lev].end(); i++) {
|
|
||||||
ILogOutput *out = *i;
|
ILogOutput *out = *i;
|
||||||
if (out->silence)
|
if (out->silence)
|
||||||
continue;
|
continue;
|
||||||
|
@ -136,6 +138,7 @@ void log_printline(enum LogMessageLevel lev, const std::string &text)
|
||||||
out->printLog(os.str(), lev);
|
out->printLog(os.str(), lev);
|
||||||
out->printLog(lev, text);
|
out->printLog(lev, text);
|
||||||
}
|
}
|
||||||
|
log_threadnamemutex.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Logbuf : public std::streambuf
|
class Logbuf : public std::streambuf
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue