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/sqlite/CMakeFiles/*
|
||||
src/sqlite/libsqlite3.a
|
||||
src/client/CMakeFiles/
|
||||
src/network/CMakeFiles/
|
||||
CMakeCache.txt
|
||||
CPackConfig.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
|
||||
set(VERSION_MAJOR 0)
|
||||
set(VERSION_MINOR 4)
|
||||
set(VERSION_PATCH 12)
|
||||
set(VERSION_PATCH 11)
|
||||
set(VERSION_PATCH_ORIG ${VERSION_PATCH})
|
||||
|
||||
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:
|
||||
$ 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.
|
||||
If you dont want git, read below on how to get the source without git.
|
||||
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
|
||||
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
||||
$ wget https://github.com/minetest/minetest/tarball/master -O master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ cd minetest-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/
|
||||
$ wget https://github.com/minetest/minetest_game/archive/master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ mv minetest_game-master minetest_game
|
||||
$ wget https://github.com/minetest/minetest_game/tarball/master -O minetest_game.tar.gz
|
||||
$ tar xf minetest_game.tar.gz
|
||||
$ mv minetest-minetest_game-* minetest_game
|
||||
$ cd ..
|
||||
|
||||
Build a version that runs directly from the source directory:
|
||||
|
@ -134,7 +122,8 @@ $ cmake . -DRUN_IN_PLACE=1
|
|||
$ make -j2
|
||||
|
||||
Run it:
|
||||
$ ./bin/minetest
|
||||
$ cd bin
|
||||
$ ./minetest
|
||||
|
||||
- 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
|
||||
|
|
|
@ -26,7 +26,7 @@ GAMES_TO_COPY = minetest_game
|
|||
# Android Version code
|
||||
# Increase for each build!
|
||||
################################################################################
|
||||
ANDROID_VERSION_CODE = 6
|
||||
ANDROID_VERSION_CODE = 5
|
||||
|
||||
################################################################################
|
||||
# toolchain config for arm old processors
|
||||
|
|
|
@ -102,6 +102,7 @@ LOCAL_C_INCLUDES := \
|
|||
|
||||
LOCAL_SRC_FILES := \
|
||||
jni/src/ban.cpp \
|
||||
jni/src/base64.cpp \
|
||||
jni/src/camera.cpp \
|
||||
jni/src/cavegen.cpp \
|
||||
jni/src/chat.cpp \
|
||||
|
@ -112,6 +113,7 @@ LOCAL_SRC_FILES := \
|
|||
jni/src/clientobject.cpp \
|
||||
jni/src/clouds.cpp \
|
||||
jni/src/collision.cpp \
|
||||
jni/src/connection.cpp \
|
||||
jni/src/content_abm.cpp \
|
||||
jni/src/content_cao.cpp \
|
||||
jni/src/content_cso.cpp \
|
||||
|
@ -188,6 +190,7 @@ LOCAL_SRC_FILES := \
|
|||
jni/src/server.cpp \
|
||||
jni/src/serverlist.cpp \
|
||||
jni/src/serverobject.cpp \
|
||||
jni/src/sha1.cpp \
|
||||
jni/src/shader.cpp \
|
||||
jni/src/sky.cpp \
|
||||
jni/src/socket.cpp \
|
||||
|
@ -196,34 +199,22 @@ LOCAL_SRC_FILES := \
|
|||
jni/src/staticobject.cpp \
|
||||
jni/src/subgame.cpp \
|
||||
jni/src/test.cpp \
|
||||
jni/src/tile.cpp \
|
||||
jni/src/tool.cpp \
|
||||
jni/src/treegen.cpp \
|
||||
jni/src/version.cpp \
|
||||
jni/src/voxel.cpp \
|
||||
jni/src/voxelalgorithms.cpp \
|
||||
jni/src/util/base64.cpp \
|
||||
jni/src/util/directiontables.cpp \
|
||||
jni/src/util/numeric.cpp \
|
||||
jni/src/util/pointedthing.cpp \
|
||||
jni/src/util/serialize.cpp \
|
||||
jni/src/util/sha1.cpp \
|
||||
jni/src/util/string.cpp \
|
||||
jni/src/util/timetaker.cpp \
|
||||
jni/src/touchscreengui.cpp \
|
||||
jni/src/database-leveldb.cpp \
|
||||
jni/src/settings.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
|
||||
jni/src/wieldmesh.cpp
|
||||
|
||||
# lua api
|
||||
LOCAL_SRC_FILES += \
|
||||
|
|
|
@ -545,11 +545,12 @@ function table.copy(t, seen)
|
|||
seen = seen or {}
|
||||
seen[t] = n
|
||||
for k, v in pairs(t) do
|
||||
n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] =
|
||||
(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v
|
||||
n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] =
|
||||
type(v) ~= "table" and v or seen[v] or table.copy(v, seen)
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- mainmenu only functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -564,7 +565,7 @@ if INIT == "mainmenu" then
|
|||
return nil
|
||||
end
|
||||
|
||||
function fgettext_ne(text, ...)
|
||||
function fgettext(text, ...)
|
||||
text = core.gettext(text)
|
||||
local arg = {n=select('#', ...), ...}
|
||||
if arg.n >= 1 then
|
||||
|
@ -586,11 +587,7 @@ if INIT == "mainmenu" then
|
|||
end
|
||||
text = result
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
function fgettext(text, ...)
|
||||
return core.formspec_escape(fgettext_ne(text, ...))
|
||||
return core.formspec_escape(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -115,20 +115,11 @@ function core.serialize(x)
|
|||
function dump_val(x)
|
||||
local tp = type(x)
|
||||
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 == "boolean" then return x and "true" or "false"
|
||||
elseif tp == "function" then
|
||||
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
|
||||
local vals = {}
|
||||
local idx_dumped = {}
|
||||
|
|
|
@ -229,28 +229,21 @@ core.register_chatcommand("setpassword", {
|
|||
if not toname then
|
||||
return false, "Name field required"
|
||||
end
|
||||
local act_str_past = "?"
|
||||
local act_str_pres = "?"
|
||||
local actstr = "?"
|
||||
if not raw_password then
|
||||
core.set_player_password(toname, "")
|
||||
act_str_past = "cleared"
|
||||
act_str_pres = "clears"
|
||||
actstr = "cleared"
|
||||
else
|
||||
core.set_player_password(toname,
|
||||
core.get_password_hash(toname,
|
||||
raw_password))
|
||||
act_str_past = "set"
|
||||
act_str_pres = "sets"
|
||||
actstr = "set"
|
||||
end
|
||||
if toname ~= name then
|
||||
core.chat_send_player(toname, "Your password was "
|
||||
.. act_str_past .. " by " .. name)
|
||||
.. actstr .. " by " .. name)
|
||||
end
|
||||
|
||||
core.log("action", name .. " " .. act_str_pres
|
||||
.. " password of " .. toname .. ".")
|
||||
|
||||
return true, "Password of player \"" .. toname .. "\" " .. act_str_past
|
||||
return true, "Password of player \"" .. toname .. "\" " .. actstr
|
||||
end,
|
||||
})
|
||||
|
||||
|
@ -264,9 +257,6 @@ core.register_chatcommand("clearpassword", {
|
|||
return false, "Name field required"
|
||||
end
|
||||
core.set_player_password(toname, '')
|
||||
|
||||
core.log("action", name .. " clears password of " .. toname .. ".")
|
||||
|
||||
return true, "Password of player \"" .. toname .. "\" cleared"
|
||||
end,
|
||||
})
|
||||
|
@ -414,14 +404,13 @@ core.register_chatcommand("set", {
|
|||
})
|
||||
|
||||
core.register_chatcommand("deleteblocks", {
|
||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
||||
params = "[here] [<pos1> <pos2>]",
|
||||
description = "delete map blocks contained in area pos1 to pos2",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local p1 = {}
|
||||
local p2 = {}
|
||||
local args = param:split(" ")
|
||||
if args[1] == "here" then
|
||||
if param == "here" then
|
||||
local player = core.get_player_by_name(name)
|
||||
if player == nil then
|
||||
core.log("error", "player is nil")
|
||||
|
@ -429,12 +418,6 @@ core.register_chatcommand("deleteblocks", {
|
|||
end
|
||||
p1 = player:getpos()
|
||||
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
|
||||
local pos1, pos2 = unpack(param:split(") ("))
|
||||
if pos1 == nil or pos2 == nil then
|
||||
|
@ -587,9 +570,6 @@ core.register_chatcommand("rollback_check", {
|
|||
.. " seconds=86400=24h, limit=5)",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local range, seconds, limit =
|
||||
param:match("(%d+) *(%d*) *(%d*)")
|
||||
range = tonumber(range) or 0
|
||||
|
@ -603,10 +583,6 @@ core.register_chatcommand("rollback_check", {
|
|||
local name = puncher:get_player_name()
|
||||
core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
|
||||
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
|
||||
if num_actions == 0 then
|
||||
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",
|
||||
privs = {rollback=true},
|
||||
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*)")
|
||||
if not target_name then
|
||||
local player_name = nil
|
||||
|
|
|
@ -106,7 +106,7 @@ function core.facedir_to_dir(facedir)
|
|||
{x=0, y=1, z=0}})
|
||||
|
||||
--indexed into by a table of correlating facedirs
|
||||
[({[0]=1, 2, 3, 4,
|
||||
[({[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
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 "
|
||||
.. def.name .. " at " .. core.pos_to_string(place_to))
|
||||
|
||||
|
||||
local oldnode = core.get_node(place_to)
|
||||
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
||||
|
||||
|
@ -357,37 +357,19 @@ function core.item_drop(itemstack, dropper, pos)
|
|||
return itemstack
|
||||
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)
|
||||
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
|
||||
|
||||
|
@ -443,7 +425,7 @@ function core.node_dig(pos, node, digger)
|
|||
|
||||
local wielded = digger:get_wielded_item()
|
||||
local drops = core.get_node_drops(node.name, wielded:get_name())
|
||||
|
||||
|
||||
local wdef = wielded:get_definition()
|
||||
local tp = wielded:get_tool_capabilities()
|
||||
local dp = core.get_dig_params(def.groups, tp)
|
||||
|
@ -456,7 +438,7 @@ function core.node_dig(pos, node, digger)
|
|||
end
|
||||
end
|
||||
digger:set_wielded_item(wielded)
|
||||
|
||||
|
||||
-- Handle drops
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
|
||||
|
@ -467,7 +449,7 @@ function core.node_dig(pos, node, digger)
|
|||
|
||||
-- Remove node and update
|
||||
core.remove_node(pos)
|
||||
|
||||
|
||||
-- Run callback
|
||||
if def.after_dig_node then
|
||||
-- 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_receive_fields = nil,
|
||||
|
||||
|
||||
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_take = core.node_metadata_inventory_take_allow_all,
|
||||
|
|
|
@ -16,15 +16,9 @@
|
|||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Global menu data
|
||||
--------------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------------
|
||||
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
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -48,25 +42,6 @@ function image_column(tooltip, flagname)
|
|||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||
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)
|
||||
local text = ""
|
||||
|
@ -93,7 +68,6 @@ function render_favorite(spec,render_details)
|
|||
end
|
||||
|
||||
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
|
||||
local clients_color = ''
|
||||
|
@ -113,17 +87,11 @@ function render_favorite(spec,render_details)
|
|||
clients_color = '#ffba97' -- 90-100%: orange
|
||||
end
|
||||
|
||||
if grey_out then
|
||||
clients_color = '#aaaaaa'
|
||||
end
|
||||
|
||||
details = details ..
|
||||
clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',' ..
|
||||
'/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
elseif grey_out then
|
||||
details = details .. '#aaaaaa,?,/,?,'
|
||||
else
|
||||
details = details .. ',?,/,?,'
|
||||
end
|
||||
|
@ -146,7 +114,7 @@ function render_favorite(spec,render_details)
|
|||
details = details .. "0,"
|
||||
end
|
||||
|
||||
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
||||
return details .. text
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -227,7 +195,7 @@ function asyncOnlineFavourites()
|
|||
nil,
|
||||
function(result)
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
menudata.favorites = order_favorite_list(result)
|
||||
menudata.favorites = result
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
end
|
||||
|
@ -257,21 +225,3 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
|||
|
||||
return retval
|
||||
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.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function modname_valid(name)
|
||||
return not name:find("[^a-z0-9_]")
|
||||
end
|
||||
|
||||
local function get_formspec(data)
|
||||
|
||||
|
@ -198,12 +195,10 @@ local function handle_buttons(this, fields)
|
|||
for i,mod in ipairs(rawlist) do
|
||||
if not mod.is_modpack and
|
||||
mod.typ ~= "game_mod" then
|
||||
if modname_valid(mod.name) then
|
||||
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
|
||||
if mod.enabled then
|
||||
worldfile:set("load_mod_"..mod.name, "true")
|
||||
else
|
||||
if mod.enabled then
|
||||
gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name)
|
||||
end
|
||||
worldfile:set("load_mod_"..mod.name, "false")
|
||||
end
|
||||
mods["load_mod_"..mod.name] = nil
|
||||
end
|
||||
|
|
|
@ -90,8 +90,6 @@ local function create_world_buttonhandler(this, fields)
|
|||
|
||||
local message = nil
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if not menudata.worldlist:uid_exists_raw(worldname) then
|
||||
core.setting_set("mg_name",fields["dd_mapgen"])
|
||||
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)
|
||||
end
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if message ~= nil then
|
||||
gamedata.errormessage = message
|
||||
else
|
||||
|
|
|
@ -139,11 +139,7 @@ local function init_globals()
|
|||
tv_main:add(tab_credits)
|
||||
|
||||
tv_main:set_global_event_handler(main_event_handler)
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_fixed_size(true)
|
||||
else
|
||||
tv_main:set_fixed_size(false)
|
||||
end
|
||||
tv_main:set_fixed_size(false)
|
||||
|
||||
if not (PLATFORM == "Android") then
|
||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
|
|
|
@ -122,36 +122,35 @@ end
|
|||
function modstore.showdownloading(title)
|
||||
local new_dlg = dialog_create("store_downloading",
|
||||
function(data)
|
||||
return "size[6,2]label[0.25,0.75;" ..
|
||||
fgettext("Downloading $1, please wait...", data.title) .. "]"
|
||||
return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
|
||||
" " .. data.title .. " " ..
|
||||
fgettext("please wait...") .. "]"
|
||||
end,
|
||||
function(this,fields)
|
||||
if fields["btn_hidden_close_download"] ~= nil then
|
||||
if fields["btn_hidden_close_download"].successfull then
|
||||
modstore.lastmodentry = fields["btn_hidden_close_download"]
|
||||
modstore.successfulldialog(this)
|
||||
modstore.successfulldialog()
|
||||
else
|
||||
this.parent:show()
|
||||
this:delete()
|
||||
modstore.lastmodtitle = ""
|
||||
end
|
||||
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
nil)
|
||||
nil,
|
||||
modstore.tv_store)
|
||||
|
||||
new_dlg:set_parent(modstore.tv_store)
|
||||
modstore.tv_store:hide()
|
||||
new_dlg.data.title = title
|
||||
new_dlg:show()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- @function [parent=#modstore] successfulldialog
|
||||
function modstore.successfulldialog(downloading_dlg)
|
||||
function modstore.successfulldialog()
|
||||
local new_dlg = dialog_create("store_downloading",
|
||||
function(data)
|
||||
local retval = ""
|
||||
|
@ -159,16 +158,18 @@ function modstore.successfulldialog(downloading_dlg)
|
|||
if modstore.lastmodentry ~= nil then
|
||||
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
|
||||
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
|
||||
|
||||
|
||||
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
|
||||
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
|
||||
|
||||
end
|
||||
retval = retval .. "button[2.2,1.5;1.5,0.5;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]"
|
||||
return retval
|
||||
retval = retval .. "button[2.5,1.5;1,0.5;btn_confirm_mod_successfull;" .. fgettext("ok") .. "]"
|
||||
end,
|
||||
function(this,fields)
|
||||
if fields["btn_confirm_mod_successfull"] ~= nil then
|
||||
this.parent:show()
|
||||
downloading_dlg:delete()
|
||||
this:hide()
|
||||
this:delete()
|
||||
|
||||
return true
|
||||
|
@ -176,10 +177,10 @@ function modstore.successfulldialog(downloading_dlg)
|
|||
|
||||
return false
|
||||
end,
|
||||
nil)
|
||||
nil,
|
||||
modstore.tv_store)
|
||||
|
||||
new_dlg:set_parent(modstore.tv_store)
|
||||
modstore.tv_store:hide()
|
||||
new_dlg.data.title = title
|
||||
new_dlg:show()
|
||||
end
|
||||
|
||||
|
@ -216,9 +217,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
end
|
||||
|
||||
if fields["btn_modstore_close"] then
|
||||
local maintab = ui.find_by_name("maintab")
|
||||
parent:hide()
|
||||
maintab:show()
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -229,7 +228,12 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
for i=1,#modstore.modlist_unsorted.data,1 do
|
||||
if modstore.modlist_unsorted.data[i].id == modid then
|
||||
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(
|
||||
function(param)
|
||||
|
@ -277,7 +281,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
texturename = modstore.modlist_unsorted.data[i].texturename
|
||||
},
|
||||
function(result)
|
||||
--print("Result from async: " .. dump(result.successfull))
|
||||
print("Result from async: " .. dump(result.successfull))
|
||||
if result.successfull then
|
||||
modmgr.installmod(result.filename,result.moddetails.basename)
|
||||
os.remove(result.filename)
|
||||
|
@ -295,7 +299,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
print("ERROR: async event failed")
|
||||
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
|
||||
end
|
||||
|
||||
parent:hide()
|
||||
modstore.showdownloading(modstore.lastmodtitle)
|
||||
return true
|
||||
end
|
||||
|
@ -387,7 +391,7 @@ function modstore.getscreenshot(ypos,listentry)
|
|||
listentry.details.screenshot_url == "") then
|
||||
|
||||
if listentry.texturename == nil then
|
||||
listentry.texturename = defaulttexturedir .. "no_screenshot.png"
|
||||
listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
return "image[0,".. ypos .. ";3,2;" ..
|
||||
|
|
|
@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
end
|
||||
|
||||
if modscreenshot == nil then
|
||||
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
||||
modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
retval = retval
|
||||
|
@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
else
|
||||
--show dependencies
|
||||
|
||||
retval = retval .. "," .. fgettext("Depends:") .. ","
|
||||
retval = retval .. ",Depends:,"
|
||||
|
||||
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=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
|
@ -89,6 +88,7 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["te_name"] ~= nil then
|
||||
gamedata.playername = 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"])
|
||||
if event.type == "DCL" 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.port = menudata.favorites[event.row].port
|
||||
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")
|
||||
if current_favourite == nil then return end
|
||||
core.delete_favorite(current_favourite)
|
||||
menudata.favorites = order_favorite_list(core.get_favorites())
|
||||
menudata.favorites = core.get_favorites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address","")
|
||||
|
@ -202,9 +198,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
return true
|
||||
end
|
||||
|
||||
if (fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and
|
||||
fields["te_port"] ~= nil then
|
||||
if fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil then
|
||||
|
||||
gamedata.playername = fields["te_name"]
|
||||
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.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
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
|
|
@ -42,10 +42,9 @@ local function get_formspec(tabview, name, tabdata)
|
|||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
|
@ -88,6 +87,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
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.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
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
|
|
@ -44,7 +44,7 @@ else()
|
|||
/usr/include/irrlicht
|
||||
)
|
||||
|
||||
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES libIrrlicht.so libIrrlicht.a Irrlicht
|
||||
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES libIrrlicht.a Irrlicht
|
||||
PATHS
|
||||
/usr/local/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/>
|
||||
* Developer Wiki: <http://dev.minetest.net/>
|
||||
|
@ -20,8 +20,7 @@ source code patches to <celeron55@gmail.com>.
|
|||
|
||||
Programming in Lua
|
||||
------------------
|
||||
If you have any difficulty in understanding this, please read
|
||||
[Programming in Lua](http://www.lua.org/pil/).
|
||||
If you have any difficulty in understanding this, please read [Programming in Lua](http://www.lua.org/pil/).
|
||||
|
||||
Startup
|
||||
-------
|
||||
|
@ -594,14 +593,13 @@ set to level from `param2`.
|
|||
Meshes
|
||||
------
|
||||
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.
|
||||
|
||||
|
||||
Noise Parameters
|
||||
----------------
|
||||
Noise Parameters, or commonly called "`NoiseParams`", define the properties of
|
||||
perlin noise.
|
||||
Noise Parameters, or commonly called "`NoiseParams`", define the properties of perlin noise.
|
||||
|
||||
### `offset`
|
||||
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.
|
||||
|
||||
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
|
||||
a non-equal distribution of ore.
|
||||
that point is greater than the `noise_threshold`, giving the ability to create a non-equal
|
||||
distribution of ore.
|
||||
|
||||
### `sheet`
|
||||
Creates a sheet of ore in a blob shape according to the 2D perlin noise
|
||||
described by `noise_params`. The relative height of the sheet can be
|
||||
controlled by the same perlin noise as well, by specifying a non-zero
|
||||
`scale` parameter in `noise_params`.
|
||||
Creates a sheet of ore in a blob shape according to the 2D perlin noise described by `noise_params`.
|
||||
The relative height of the sheet can be controlled by the same perlin noise as well, by specifying
|
||||
a non-zero `scale` parameter in `noise_params`.
|
||||
|
||||
**IMPORTANT**: The noise is not transformed by `offset` or `scale` when comparing
|
||||
against the noise threshold, but scale is used to determine relative height.
|
||||
**IMPORTANT**: The noise is not transformed by `offset` or `scale` when comparing against the noise
|
||||
threshold, but scale is used to determine relative height.
|
||||
The height of the blob is randomly scattered, with a maximum height of `clust_size`.
|
||||
|
||||
`clust_scarcity` and `clust_num_ores` are ignored.
|
||||
|
||||
This is essentially an improved version of the so-called "stratus" ore seen in
|
||||
some unofficial mods.
|
||||
This is essentially an improved version of the so-called "stratus" ore seen in some unofficial mods.
|
||||
|
||||
### `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
|
||||
`clust_scarcity` has the same meaning as with the `scatter` type.
|
||||
### `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.
|
||||
|
||||
### `simple`
|
||||
Creates a 1 times `H` times 1 column of a specified node (or a random node from
|
||||
a list, if a decoration list is specified). Can specify a certain node it must
|
||||
spawn next to, such as water or lava, for example. Can also generate a
|
||||
decoration of random height between a specified lower and upper bound.
|
||||
This type of decoration is intended for placement of grass, flowers, cacti,
|
||||
papyri, and so on.
|
||||
Creates a 1 times `H` times 1 column of a specified node (or a random node from a list, if a
|
||||
decoration list is specified). Can specify a certain node it must spawn next to, such as water or
|
||||
lava, for example. Can also generate a decoration of random height between a specified lower and
|
||||
upper bound. This type of decoration is intended for placement of grass, flowers, cacti, papyri,
|
||||
and so on.
|
||||
|
||||
### `schematic`
|
||||
Copies a box of `MapNodes` from a specified schematic file (or raw description).
|
||||
Can specify a probability of a node randomly appearing when placed.
|
||||
This decoration type is intended to be used for multi-node sized discrete
|
||||
structures, such as trees, cave spikes, rocks, and so on.
|
||||
Copies a box of `MapNodes` from a specified schematic file (or raw description). Can specify a
|
||||
probability of a node randomly appearing when placed. This decoration type is intended to be used
|
||||
for multi-node sized discrete structures, such as trees, cave spikes, rocks, and so on.
|
||||
|
||||
|
||||
Schematic specifier
|
||||
--------------------
|
||||
A schematic specifier identifies a schematic by either a filename to a
|
||||
Minetest Schematic file (`.mts`) or through raw data supplied through Lua,
|
||||
in the form of a table. This table must specify two fields:
|
||||
A schematic specifier identifies a schematic by either a filename to a Minetest Schematic file (`.mts`)
|
||||
or through raw data supplied through Lua, 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 `data` field is a flat table of MapNodes making up the schematic,
|
||||
in the order of `[z [y [x]]]`.
|
||||
* The `data` field is a flat table of MapNodes making up the schematic, in the order of `[z [y [x]]]`.
|
||||
|
||||
**Important**: The default value for `param1` in MapNodes here is `255`,
|
||||
which represents "always place".
|
||||
**Important**: The default value for `param1` in MapNodes here is `255`, which represents "always place".
|
||||
|
||||
In the bulk `MapNode` data, `param1`, instead of the typical light values,
|
||||
instead represents the probability of that node appearing in the structure.
|
||||
In the bulk `MapNode` data, `param1`, instead of the typical light values, instead represents the
|
||||
probability of that node appearing in the structure.
|
||||
|
||||
When passed to `minetest.create_schematic`, probability is an integer value
|
||||
ranging from `0` to `255`:
|
||||
When passed to `minetest.create_schematic`, probability is an integer value ranging from `0` to `255`:
|
||||
|
||||
* 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).
|
||||
* If the probability value `p` is greater than `0`, then there is a
|
||||
`(p / 256 * 100)`% chance that node will appear when the schematic is
|
||||
placed on the map.
|
||||
* If the probability value `p` is greater than `0`, then there is a `(p / 256 * 100)`% chance that node
|
||||
will appear when the schematic is placed on the map.
|
||||
|
||||
**Important note**: Node aliases cannot be used for a raw schematic provided
|
||||
when registering as a decoration.
|
||||
**Important note**: Node aliases cannot be used for a raw schematic provided when registering as a decoration.
|
||||
|
||||
|
||||
Schematic attributes
|
||||
--------------------
|
||||
See section "Flag Specifier Format".
|
||||
|
||||
Currently supported flags: `place_center_x`, `place_center_y`,
|
||||
`place_center_z`, `force_placement`.
|
||||
Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`.
|
||||
|
||||
* `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_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
|
||||
-----------------
|
||||
The position field is used for all element types.
|
||||
|
||||
To account for differing resolutions, the position coordinates are the percentage
|
||||
of the screen, ranging in value from `0` to `1`.
|
||||
To account for differing resolutions, the position coordinates are the percentage of the screen,
|
||||
ranging in value from `0` to `1`.
|
||||
|
||||
The name field is not yet used, but should contain a description of what the
|
||||
HUD element represents. The direction field is the direction in which something
|
||||
is drawn.
|
||||
The name field is not yet used, but should contain a description of what the HUD element represents.
|
||||
The direction field is the direction in which something is drawn.
|
||||
|
||||
`0` draws from left to right, `1` draws from right to left, `2` draws from
|
||||
top to bottom, and `3` draws from bottom to top.
|
||||
`0` draws from left to right, `1` draws from right to left, `2` draws from top to bottom,
|
||||
and `3` draws from bottom to top.
|
||||
|
||||
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.
|
||||
|
@ -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.
|
||||
|
||||
**Note**: Future revisions to the HUD API may be incompatible; the HUD API is still
|
||||
in the experimental stages.
|
||||
**Note**: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages.
|
||||
|
||||
### `image`
|
||||
Displays an image on the HUD.
|
||||
|
@ -892,18 +876,15 @@ For helper functions see "Vector helpers".
|
|||
|
||||
Flag Specifier Format
|
||||
---------------------
|
||||
Flags using the standardized flag specifier format can be specified in either of
|
||||
two ways, by string or table.
|
||||
Flags using the standardized flag specifier format can be specified in either of two ways, by string or table.
|
||||
|
||||
The string format is a comma-delimited set of flag names; whitespace and
|
||||
unrecognized flag fields are ignored. Specifying a flag in the string sets the
|
||||
flag, and specifying a flag prefixed by the string `"no"` explicitly
|
||||
The string format is a comma-delimited set of flag names; whitespace and unrecognized flag fields are ignored.
|
||||
Specifying a flag in the string sets the flag, and specifying a flag prefixed by the string `"no"` explicitly
|
||||
clears the flag from whatever the default may be.
|
||||
|
||||
In addition to the standard string flag format, the schematic flags field can
|
||||
also be a table of flag names to boolean values representing whether or not the
|
||||
flag is set. Additionally, if a field with the flag name prefixed with `"no"`
|
||||
is present, mapped to a boolean of any value, the specified flag is unset.
|
||||
In addition to the standard string flag format, the schematic flags field can also be a table of flag names
|
||||
to boolean values representing whether or not the flag is set. Additionally, if a field with the flag name
|
||||
prefixed with `"no"` is present, mapped to a boolean of any value, the specified flag is unset.
|
||||
|
||||
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
|
||||
checked.
|
||||
* `soil`: saplings will grow on nodes in this group
|
||||
* `connect_to_raillike`: makes nodes of raillike drawtype with same group value
|
||||
connect to each other
|
||||
* `connect_to_raillike`: makes nodes of raillike drawtype connect to
|
||||
other group members with same drawtype
|
||||
|
||||
### Known damage and digging time defining groups
|
||||
* `crumbly`: dirt, sand
|
||||
|
@ -1196,8 +1177,7 @@ Damage calculation:
|
|||
|
||||
damage = 0
|
||||
foreach group in cap.damage_groups:
|
||||
damage += cap.damage_groups[group] * limit(actual_interval /
|
||||
cap.full_punch_interval, 0.0, 1.0)
|
||||
damage += cap.damage_groups[group] * limit(actual_interval / cap.full_punch_interval, 0.0, 1.0)
|
||||
* (object.armor_groups[group] / 100.0)
|
||||
-- Where object.armor_groups[group] is 0 for inexistent values
|
||||
return damage
|
||||
|
@ -1205,7 +1185,7 @@ Damage calculation:
|
|||
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
|
||||
pre-defined somehow (e.g. by defining a sprite animation) (not implemented;
|
||||
TODO).
|
||||
TODO).
|
||||
Currently a smoke puff will appear when an entity dies.
|
||||
|
||||
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)
|
||||
|
||||
This should never be called directly, because damage is usually not handled by
|
||||
the entity itself.
|
||||
This should never be called directly, because damage is usually not handled by the entity
|
||||
itself.
|
||||
|
||||
* `puncher` is the object performing the punch. Can be `nil`. Should never be
|
||||
accessed unless absolutely required, to encourage interoperability.
|
||||
|
@ -1264,14 +1244,12 @@ Example stuff:
|
|||
print(dump(meta:to_table()))
|
||||
meta:from_table({
|
||||
inventory = {
|
||||
main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "",
|
||||
[5] = "", [6] = "", [7] = "", [8] = "", [9] = "",
|
||||
[10] = "", [11] = "", [12] = "", [13] = "",
|
||||
[14] = "default:cobble", [15] = "", [16] = "", [17] = "",
|
||||
[18] = "", [19] = "", [20] = "default:cobble", [21] = "",
|
||||
[22] = "", [23] = "", [24] = "", [25] = "", [26] = "",
|
||||
[27] = "", [28] = "", [29] = "", [30] = "", [31] = "",
|
||||
[32] = ""}
|
||||
main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "", [5] = "", [6] = "",
|
||||
[7] = "", [8] = "", [9] = "", [10] = "", [11] = "", [12] = "", [13] = "",
|
||||
[14] = "default:cobble", [15] = "", [16] = "", [17] = "", [18] = "",
|
||||
[19] = "", [20] = "default:cobble", [21] = "", [22] = "", [23] = "",
|
||||
[24] = "", [25] = "", [26] = "", [27] = "", [28] = "", [29] = "", [30] = "",
|
||||
[31] = "", [32] = ""}
|
||||
},
|
||||
fields = {
|
||||
formspec = "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"`
|
||||
* `minetest.find_nodes_in_area(minp, maxp, nodenames)`: returns a list of positions
|
||||
* `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(seeddiff, octaves, persistence, scale)`
|
||||
* 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`.
|
||||
* `minetest.set_mapgen_params(MapgenParams)`
|
||||
* Set map generation parameters
|
||||
* Function cannot be called after the registration period; only initialization
|
||||
and `on_mapgen_init`
|
||||
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`,
|
||||
and `flags`.
|
||||
* Function cannot be called after the registration period; only initialization and `on_mapgen_init`
|
||||
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`, and `flags`.
|
||||
* Leave field unset to leave that parameter unchanged
|
||||
* `flags` contains a comma-delimited string of flags to set,
|
||||
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`
|
||||
* callbacks: See "Detached inventory callbacks"
|
||||
* 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
|
||||
* `minetest.show_formspec(playername, formname, formspec)`
|
||||
|
@ -2067,11 +2037,7 @@ These functions return the leftover itemstack.
|
|||
* `minetest.item_drop(itemstack, dropper, pos)`
|
||||
* Drop the item
|
||||
* `minetest.item_eat(hp_change, replace_with_item)`
|
||||
* Eat the item.
|
||||
* `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`
|
||||
* Eat the item. `replace_with_item` can be `nil`.
|
||||
|
||||
### Defaults for the `on_punch` and `on_dig` node definition callbacks
|
||||
* `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.
|
||||
* 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`.
|
||||
* `pos` is the 3D vector specifying the absolute coordinates of the
|
||||
node being modified,
|
||||
* `pos` is the 3D vector specifying the absolute coordinates of the node being modified,
|
||||
* `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
|
||||
last entry is used.
|
||||
* If there are two or more entries with the same pos value, the last entry is used.
|
||||
* If `pos` is not inside the box formed by `p1` and `p2`, it is ignored.
|
||||
* If `probability_list` equals `nil`, no probabilities are applied.
|
||||
* Slice probability works in the same manner, except takes a field
|
||||
called `ypos` instead which
|
||||
* Slice probability works in the same manner, except takes a field called `ypos` instead which
|
||||
indicates the y position of the slice with a probability applied.
|
||||
* If slice probability list equals `nil`, no slice probabilities are applied.
|
||||
* Saves schematic in the Minetest Schematic format to filename.
|
||||
|
@ -2281,7 +2244,7 @@ Class reference
|
|||
---------------
|
||||
|
||||
### `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)`.
|
||||
|
||||
#### Methods
|
||||
|
@ -2297,7 +2260,7 @@ Can be gotten via `minetest.get_meta(pos)`.
|
|||
* See "Node Metadata"
|
||||
|
||||
### `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)`.
|
||||
|
||||
#### Methods
|
||||
|
@ -2325,7 +2288,6 @@ This is basically a reference to a C++ `ServerActiveObject`
|
|||
|
||||
#### Methods
|
||||
* `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}`
|
||||
* `setpos(pos)`; `pos`=`{x=num, y=num, z=num}`
|
||||
* `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`)
|
||||
* `sneak`: whether player can sneak (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
|
||||
number on success
|
||||
* `hud_add(hud definition)`: add a HUD element described by HUD def, returns ID number on success
|
||||
* `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
|
||||
* 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)`
|
||||
* `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount
|
||||
* `nil`: Disables override, defaulting to sunlight based on day-night cycle
|
||||
* `set_local_animation(walk, dig, walk+dig, frame_speed=frame_speed)`
|
||||
|
||||
set animation for player model in third person view
|
||||
|
||||
set_local_animation({x=0, y=79}, -- < stand/idle animation key frames
|
||||
{x=168, y=187}, -- < walk animation key frames
|
||||
{x=189, y=198}, -- < dig animation key frames
|
||||
{x=200, y=219}, -- < walk+dig animation key frames
|
||||
frame_speed=30): -- < animation 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
|
||||
* stand/idle animation key frames
|
||||
* walk animation key frames
|
||||
* dig animation key frames
|
||||
* walk+dig animation key frames
|
||||
* 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
|
||||
* in first person view
|
||||
* 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`
|
||||
A perlin noise generator.
|
||||
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)`
|
||||
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.
|
||||
|
||||
#### Methods
|
||||
* `read_from_map(p1, p2)`: Reads a chunk of map from the map containing the
|
||||
region formed by `p1` and `p2`.
|
||||
* `read_from_map(p1, p2)`: Reads a chunk of map from the map containing the region formed by `p1` and `p2`.
|
||||
* returns actual emerged `pmin`, actual emerged `pmax`
|
||||
* `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
|
||||
* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded in
|
||||
the `VoxelManip` at that position
|
||||
* `set_node_at(pos, node)`: Sets a specific `MapNode` in the `VoxelManip` at
|
||||
that position
|
||||
* `get_node_at(pos)`: Returns a `MapNode` table of the node currently loaded 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
|
||||
* 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
|
||||
* `update_map()`: Update map after writing chunk back to map.
|
||||
* To be used only by `VoxelManip` objects created by the mod itself;
|
||||
not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object`
|
||||
* To be used only by `VoxelManip` objects created by the mod itself; not a `VoxelManip` that was
|
||||
retrieved from `minetest.get_mapgen_object`
|
||||
* `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>}`
|
||||
* 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 if left out
|
||||
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area if left out
|
||||
* `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`
|
||||
* Each value is the bitwise combination of day and night light values (`0` to `15` each)
|
||||
* `light = day + (night * 16)`
|
||||
* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node
|
||||
in the `VoxelManip`
|
||||
* `set_light_data(light_data)`: Sets the `param1` (light) contents of each node in the `VoxelManip`
|
||||
* 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
|
||||
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
||||
* `calc_lighting(p1, p2)`: Calculate lighting within the `VoxelManip`
|
||||
* 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
|
||||
if left out
|
||||
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area if left out
|
||||
* `update_liquids()`: Update liquid flow
|
||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator
|
||||
had been modified since the last read from map, due to a call to
|
||||
`minetest.set_data()` on the loaded area elsewhere
|
||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator had been modified since
|
||||
the last read from map, due to a call to `minetest.set_data()` on the loaded area elsewhere
|
||||
* `get_emerged_area()`: Returns actual emerged minimum and maximum positions.
|
||||
|
||||
### `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.
|
||||
|
||||
#### Methods
|
||||
* `getExtent()`: returns a 3D vector containing the size of the area formed by
|
||||
`MinEdge` and `MaxEdge`
|
||||
* `getExtent()`: returns a 3D vector containing the size 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`
|
||||
* useful for things like `VoxelManip`, raw Schematic specifiers,
|
||||
`PerlinNoiseMap:get2d`/`3dMap`, and so on
|
||||
* useful for things like `VoxelManip`, raw Schematic specifiers, `PerlinNoiseMap:get2d`/`3dMap`, and so on
|
||||
* `indexp(p)`: same as above, except takes a vector
|
||||
* `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`
|
||||
|
@ -2638,39 +2587,37 @@ It can be created via `Settings(filename)`.
|
|||
|
||||
Mapgen objects
|
||||
--------------
|
||||
A mapgen object is a construct used in map generation. Mapgen objects can be used
|
||||
by an `on_generate` callback to speed up operations by avoiding unnecessary
|
||||
recalculations; these can be retrieved using the `minetest.get_mapgen_object()`
|
||||
function. If the requested Mapgen object is unavailable, or `get_mapgen_object()`
|
||||
was called outside of an `on_generate()` callback, `nil` is returned.
|
||||
A mapgen object is a construct used in map generation. Mapgen objects can be used by an `on_generate`
|
||||
callback to speed up operations by avoiding unnecessary recalculations; these can be retrieved using the
|
||||
`minetest.get_mapgen_object()` function. If the requested Mapgen object is unavailable, or
|
||||
`get_mapgen_object()` was called outside of an `on_generate()` callback, `nil` is returned.
|
||||
|
||||
The following Mapgen objects are currently available:
|
||||
|
||||
### `voxelmanip`
|
||||
This returns three values; the `VoxelManip` object to be used, minimum and maximum
|
||||
emerged position, in that order. All mapgens support this object.
|
||||
This returns three values; the `VoxelManip` object to be used, minimum and maximum emerged position, in that
|
||||
order. All mapgens support this object.
|
||||
|
||||
### `heightmap`
|
||||
Returns an array containing the y coordinates of the ground levels of nodes in
|
||||
the most recently generated chunk by the current mapgen.
|
||||
Returns an array containing the y coordinates of the ground levels of nodes in the most recently
|
||||
generated chunk by the current mapgen.
|
||||
|
||||
### `biomemap`
|
||||
Returns an array containing the biome IDs of nodes in the most recently
|
||||
generated chunk by the current mapgen.
|
||||
Returns an array containing the biome IDs of nodes in the most recently generated chunk by the
|
||||
current mapgen.
|
||||
|
||||
### `heatmap`
|
||||
Returns an array containing the temperature values of nodes in the most
|
||||
recently generated chunk by the current mapgen.
|
||||
Returns an array containing the temperature values of nodes in the most recently generated chunk by
|
||||
the current mapgen.
|
||||
|
||||
### `humiditymap`
|
||||
Returns an array containing the humidity values of nodes in the most recently
|
||||
generated chunk by the current mapgen.
|
||||
Returns an array containing the humidity values of nodes in the most recently generated chunk by the
|
||||
current mapgen.
|
||||
|
||||
### `gennotify`
|
||||
Returns a table mapping requested generation notification types to arrays of
|
||||
positions at which the corresponding generated structures are located at within
|
||||
the current chunk. To set the capture of positions of interest to be recorded
|
||||
on generate, use `minetest.set_gen_notify()`.
|
||||
Returns a table mapping requested generation notification types to arrays of positions at which the
|
||||
corresponding generated structures are located at within the current chunk. To set the capture of positions
|
||||
of interest to be recorded on generate, use `minetest.set_gen_notify()`.
|
||||
|
||||
Possible fields of the table returned are:
|
||||
|
||||
|
@ -2682,8 +2629,7 @@ Possible fields of the table returned are:
|
|||
* `large_cave_end`
|
||||
* `decoration`
|
||||
|
||||
Decorations have a key in the format of `"decoration#id"`, where `id` is the
|
||||
numeric unique decoration ID.
|
||||
Decorations have a key in the format of `"decoration#id"`, where `id` is the numeric unique decoration ID.
|
||||
|
||||
Registered entities
|
||||
-------------------
|
||||
|
@ -2730,8 +2676,7 @@ L-system trees
|
|||
angle, --num angle in deg
|
||||
iterations, --num max # of iterations, usually 2 -5
|
||||
random_level, --num factor to lower nr of iterations, usually 0 - 3
|
||||
trunk_type, --string single/double/crossed) type of trunk: 1 node,
|
||||
-- 2x2 nodes or 3x3 in cross shape
|
||||
trunk_type, --string single/double/crossed) type of trunk: 1 node, 2x2 nodes or 3x3 in cross shape
|
||||
thin_branches, --boolean true -> use thin (1 node) branches
|
||||
fruit, --string fruit node name
|
||||
fruit_chance, --num chance (0-100) to replace leaves with fruit node
|
||||
|
@ -3193,10 +3138,8 @@ Definition tables
|
|||
schematic = {
|
||||
size = {x=4, y=6, z=4},
|
||||
data = {
|
||||
{name="default:cobble", param1=255, param2=0},
|
||||
{name="default:dirt_with_grass", param1=255, param2=0},
|
||||
{name="ignore", param1=255, param2=0},
|
||||
{name="air", param1=255, param2=0},
|
||||
{name="cobble", param1=255, param2=0},
|
||||
{name="dirt_with_grass", param1=255, param2=0},
|
||||
...
|
||||
},
|
||||
yslice_prob = {
|
||||
|
@ -3207,7 +3150,7 @@ Definition tables
|
|||
},
|
||||
-- ^ See 'Schematic specifier' for details.
|
||||
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'.
|
||||
rotation = "90" -- rotate schematic 90 degrees on placement
|
||||
-- ^ 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
|
||||
|
@ -197,11 +197,9 @@ core.delete_world(index)
|
|||
Helpers:
|
||||
core.gettext(string) -> string
|
||||
^ 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
|
||||
^ 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)
|
||||
^ see core.parse_json (lua_api.txt)
|
||||
dump(obj, dumped={})
|
||||
|
@ -213,12 +211,6 @@ string:trim()
|
|||
core.is_yes(arg) (possible in async calls)
|
||||
^ 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:
|
||||
core.handle_async(async_job,parameters,finished)
|
||||
^ execute a function asynchronously
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#keymap_rangeselect = KEY_KEY_R
|
||||
#keymap_freemove = KEY_KEY_K
|
||||
#keymap_fastmove = KEY_KEY_J
|
||||
#keymap_cinematic = KEY_F8
|
||||
#keymap_screenshot = KEY_F12
|
||||
# If true, keymap_special1 instead of keymap_sneak is used for climbing down and descending
|
||||
#aux1_descends = false
|
||||
|
@ -128,13 +127,6 @@
|
|||
#free_move = false
|
||||
# Continuous forward movement (for testing)
|
||||
#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_move = false
|
||||
# Invert mouse
|
||||
|
@ -260,16 +252,16 @@
|
|||
#freetype = true
|
||||
# Path to TrueTypeFont or bitmap
|
||||
#font_path = fonts/liberationsans.ttf
|
||||
#font_size = 15
|
||||
#font_size = 13
|
||||
# Font shadow offset, if 0 then shadow will not be drawn
|
||||
#font_shadow = 1
|
||||
# Font shadow alpha (opaqueness, between 0 and 255)
|
||||
#font_shadow_alpha = 128
|
||||
#mono_font_path = fonts/liberationmono.ttf
|
||||
#mono_font_size = 15
|
||||
#mono_font_size = 13
|
||||
# This font will be used for certain languages
|
||||
#fallback_font_path = fonts/DroidSansFallbackFull.ttf
|
||||
#fallback_font_size = 15
|
||||
#fallback_font_size = 13
|
||||
#fallback_font_shadow = 1
|
||||
#fallback_font_shadow_alpha = 128
|
||||
# Override language. When no value is provided (default) system language is used.
|
||||
|
@ -345,7 +337,6 @@
|
|||
# If true, disable cheat prevention in multiplayer
|
||||
#disable_anticheat = false
|
||||
# If true, actions are recorded for rollback
|
||||
# This option is only read when server starts
|
||||
#enable_rollback_recording = false
|
||||
# Handling for deprecated lua api calls:
|
||||
# "legacy" = (try to) mimic old behaviour (default for release).
|
||||
|
@ -469,8 +460,6 @@
|
|||
# Controls size of deserts and beaches in Mapgen V6
|
||||
#mgv6_freq_desert = 0.45
|
||||
#mgv6_freq_beach = 0.15
|
||||
# Enable/disable floating dungeons and dungeon slices
|
||||
#enable_floating_dungeons = true
|
||||
|
||||
# Perlin noise attributes for different map generation parameters.
|
||||
# Noise parameters can be specified as a set of positional values:
|
||||
|
@ -488,14 +477,33 @@
|
|||
# flags = "defaults"
|
||||
#}
|
||||
# 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,
|
||||
# other noise parameters are shown in positional format to save space.
|
||||
# Mgv5 uses eased noise for np_cave1, np_cave2, np_ground and np_crumble, so these are shown in
|
||||
# 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_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_cave1 = 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
|
||||
#mgv5_np_cave2 = 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
|
||||
#mgv5_np_cave1 = {
|
||||
# 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 = {
|
||||
# offset = 0
|
||||
# scale = 40
|
||||
|
@ -506,6 +514,17 @@
|
|||
# lacunarity = 2.0
|
||||
# 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_np_terrain_base = -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
Name=Minetest
|
||||
GenericName=Minetest
|
||||
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
|
||||
Icon=minetest-icon
|
||||
Terminal=false
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,18 +7,18 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: minetest\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-02-14 13:50+0100\n"
|
||||
"PO-Revision-Date: 2015-02-14 13:35+0100\n"
|
||||
"POT-Creation-Date: 2014-12-13 15:24+0100\n"
|
||||
"PO-Revision-Date: 2015-01-19 09:56+0100\n"
|
||||
"Last-Translator: Diego de las Heras <diegodelasheras@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\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"
|
||||
msgstr "Aceptar"
|
||||
|
||||
|
@ -40,7 +40,7 @@ msgstr "Ocultar contenido mp"
|
|||
msgid "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:"
|
||||
msgstr "Dependencias:"
|
||||
|
||||
|
@ -124,7 +124,7 @@ msgstr "¿Realmente desea borrar \"$1\"?"
|
|||
|
||||
#: builtin/mainmenu/dlg_delete_mod.lua:27
|
||||
#: builtin/mainmenu/dlg_delete_world.lua:25
|
||||
#: builtin/mainmenu/tab_settings.lua:79
|
||||
#: builtin/mainmenu/tab_settings.lua:25
|
||||
msgid "Yes"
|
||||
msgstr "Sí"
|
||||
|
||||
|
@ -186,40 +186,48 @@ msgstr "Instalar mod: Imposible encontrar el nombre real del mod para: $1"
|
|||
msgid "Unsorted"
|
||||
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"
|
||||
msgstr "Buscar"
|
||||
|
||||
#: builtin/mainmenu/store.lua:126
|
||||
msgid "Downloading $1, please wait..."
|
||||
msgstr "Descargando $1, por favor espere..."
|
||||
#: builtin/mainmenu/store.lua:125
|
||||
msgid "Downloading"
|
||||
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:"
|
||||
msgstr "Instalado con éxito:"
|
||||
|
||||
#: builtin/mainmenu/store.lua:162
|
||||
#: builtin/mainmenu/store.lua:163
|
||||
msgid "Shortname:"
|
||||
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"
|
||||
msgstr "Clasificación"
|
||||
|
||||
#: builtin/mainmenu/store.lua:497
|
||||
#: builtin/mainmenu/store.lua:501
|
||||
msgid "re-Install"
|
||||
msgstr "Reinstalar"
|
||||
|
||||
#: builtin/mainmenu/store.lua:499
|
||||
#: builtin/mainmenu/store.lua:503
|
||||
msgid "Install"
|
||||
msgstr "Instalar"
|
||||
|
||||
# En el menú principal de mods pone repositorio no tienda.
|
||||
#: builtin/mainmenu/store.lua:518
|
||||
#: builtin/mainmenu/store.lua:522
|
||||
msgid "Close store"
|
||||
msgstr "Cerrar repositorio"
|
||||
|
||||
#: builtin/mainmenu/store.lua:526
|
||||
#: builtin/mainmenu/store.lua:530
|
||||
msgid "Page $1 of $2"
|
||||
msgstr "Página $1 de $2"
|
||||
|
||||
|
@ -280,7 +288,8 @@ msgstr "Mods"
|
|||
msgid "Address / Port :"
|
||||
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 :"
|
||||
msgstr "Nombre / contraseña:"
|
||||
|
||||
|
@ -299,22 +308,7 @@ msgstr "Borrar"
|
|||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#: builtin/mainmenu/tab_multiplayer.lua:62
|
||||
#: 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
|
||||
#: builtin/mainmenu/tab_multiplayer.lua:252
|
||||
msgid "Client"
|
||||
msgstr "Cliente"
|
||||
|
||||
|
@ -334,12 +328,12 @@ msgstr "Iniciar juego"
|
|||
msgid "Select World:"
|
||||
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
|
||||
msgid "Creative Mode"
|
||||
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
|
||||
msgid "Enable Damage"
|
||||
msgstr "Permitir daños"
|
||||
|
@ -348,11 +342,6 @@ msgstr "Permitir daños"
|
|||
msgid "Public"
|
||||
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
|
||||
msgid "Bind Address"
|
||||
msgstr "Asociar dirección"
|
||||
|
@ -369,151 +358,133 @@ msgstr "Puerto del servidor:"
|
|||
msgid "Server"
|
||||
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
|
||||
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?"
|
||||
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!!!"
|
||||
msgstr "¡¡¡No!!!"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:181
|
||||
#: builtin/mainmenu/tab_settings.lua:134
|
||||
msgid "Smooth Lighting"
|
||||
msgstr "Iluminación suave"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:183
|
||||
#: builtin/mainmenu/tab_settings.lua:136
|
||||
msgid "Enable Particles"
|
||||
msgstr "Habilitar partículas"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:185
|
||||
#: builtin/mainmenu/tab_settings.lua:138
|
||||
msgid "3D Clouds"
|
||||
msgstr "Nubes 3D"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:187
|
||||
#: builtin/mainmenu/tab_settings.lua:141
|
||||
msgid "Fancy Trees"
|
||||
msgstr "Árboles detallados"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:189
|
||||
#: builtin/mainmenu/tab_settings.lua:142
|
||||
msgid "Opaque Water"
|
||||
msgstr "Agua opaca"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:191
|
||||
#: builtin/mainmenu/tab_settings.lua:145
|
||||
msgid "Connected Glass"
|
||||
msgstr "Vidrios conectados"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:193
|
||||
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
|
||||
#: builtin/mainmenu/tab_settings.lua:149
|
||||
msgid "Restart minetest for driver change to take effect"
|
||||
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"
|
||||
msgstr "Sombreadores"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:212
|
||||
#: builtin/mainmenu/tab_settings.lua:164
|
||||
msgid "Change keys"
|
||||
msgstr "Configurar teclas"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:215
|
||||
#: builtin/mainmenu/tab_settings.lua:167
|
||||
msgid "Reset singleplayer world"
|
||||
msgstr "Reiniciar mundo de un jugador"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:219
|
||||
#: builtin/mainmenu/tab_settings.lua:171
|
||||
msgid "GUI scale factor"
|
||||
msgstr "Factor de escala (GUI)"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:223
|
||||
#: builtin/mainmenu/tab_settings.lua:175
|
||||
msgid "Scaling factor applied to menu elements: "
|
||||
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"
|
||||
msgstr "Tocar para interactuar"
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:235
|
||||
#: builtin/mainmenu/tab_settings.lua:187
|
||||
msgid "Touchthreshold (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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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."
|
||||
msgstr "Para habilitar los sombreadores debe utilizar el controlador OpenGL."
|
||||
|
||||
#: builtin/mainmenu/tab_settings.lua:398
|
||||
#: builtin/mainmenu/tab_settings.lua:330
|
||||
msgid "Settings"
|
||||
msgstr "Configuración"
|
||||
|
||||
#: builtin/mainmenu/tab_simple_main.lua:79
|
||||
#: builtin/mainmenu/tab_simple_main.lua:67
|
||||
msgid "Fly mode"
|
||||
msgstr "Modo vuelo"
|
||||
|
||||
#: builtin/mainmenu/tab_simple_main.lua:83
|
||||
#: builtin/mainmenu/tab_simple_main.lua:71
|
||||
msgid "Start Singleplayer"
|
||||
msgstr "Comenzar un jugador"
|
||||
|
||||
#: builtin/mainmenu/tab_simple_main.lua:84
|
||||
#: builtin/mainmenu/tab_simple_main.lua:72
|
||||
msgid "Config mods"
|
||||
msgstr "Configurar mods"
|
||||
|
||||
#: builtin/mainmenu/tab_simple_main.lua:203
|
||||
#: builtin/mainmenu/tab_simple_main.lua:191
|
||||
msgid "Main"
|
||||
msgstr "Principal"
|
||||
|
||||
|
@ -538,195 +509,39 @@ msgstr "Sin información disponible"
|
|||
msgid "Texturepacks"
|
||||
msgstr "Texturas"
|
||||
|
||||
#: src/client.cpp:2788
|
||||
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
|
||||
#: src/client.cpp:2726
|
||||
msgid "Item textures..."
|
||||
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
|
||||
msgid "needs_fallback_font"
|
||||
msgstr "needs_fallback_font"
|
||||
|
||||
#: src/game.cpp:1057 src/guiFormSpecMenu.cpp:2006
|
||||
msgid "Proceed"
|
||||
msgstr "Continuar"
|
||||
|
||||
#: src/game.cpp:1077
|
||||
msgid "You died."
|
||||
msgstr "Has muerto."
|
||||
|
||||
#: src/game.cpp:1078
|
||||
#: src/game.cpp:1063
|
||||
msgid "Respawn"
|
||||
msgstr "Revivir"
|
||||
|
||||
#: src/game.cpp:1097
|
||||
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
|
||||
#: src/game.cpp:2250
|
||||
msgid "Item definitions..."
|
||||
msgstr "Definiciones de objetos..."
|
||||
|
||||
#: src/game.cpp:2279
|
||||
#: src/game.cpp:2255
|
||||
msgid "Node definitions..."
|
||||
msgstr "Definiciones de nodos..."
|
||||
|
||||
#: src/game.cpp:2286
|
||||
#: src/game.cpp:2262
|
||||
msgid "Media..."
|
||||
msgstr "Media..."
|
||||
|
||||
#: src/game.cpp:2291
|
||||
#: src/game.cpp:2267
|
||||
msgid " KB/s"
|
||||
msgstr " KB/s"
|
||||
|
||||
#: src/game.cpp:2295
|
||||
#: src/game.cpp:2271
|
||||
msgid " MB/s"
|
||||
msgstr " MB/s"
|
||||
|
||||
#: src/game.cpp:4210
|
||||
#: src/game.cpp:4220
|
||||
msgid ""
|
||||
"\n"
|
||||
"Check debug.txt for details."
|
||||
|
@ -734,14 +549,14 @@ msgstr ""
|
|||
"\n"
|
||||
"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 "
|
||||
msgstr "Ingresar "
|
||||
|
||||
#: src/guiFormSpecMenu.cpp:2817
|
||||
msgid "ok"
|
||||
msgstr "aceptar"
|
||||
|
||||
#: src/guiKeyChangeMenu.cpp:125
|
||||
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
||||
msgstr ""
|
||||
|
@ -832,23 +647,23 @@ msgstr "Seleccionar distancia"
|
|||
msgid "Print stacks"
|
||||
msgstr "Imprimir pilas"
|
||||
|
||||
#: src/guiPasswordChange.cpp:108
|
||||
#: src/guiPasswordChange.cpp:106
|
||||
msgid "Old Password"
|
||||
msgstr "Contraseña anterior"
|
||||
|
||||
#: src/guiPasswordChange.cpp:124
|
||||
#: src/guiPasswordChange.cpp:122
|
||||
msgid "New Password"
|
||||
msgstr "Contraseña nueva"
|
||||
|
||||
#: src/guiPasswordChange.cpp:139
|
||||
#: src/guiPasswordChange.cpp:137
|
||||
msgid "Confirm Password"
|
||||
msgstr "Confirmar contraseña"
|
||||
|
||||
#: src/guiPasswordChange.cpp:155
|
||||
#: src/guiPasswordChange.cpp:153
|
||||
msgid "Change"
|
||||
msgstr "Cambiar"
|
||||
|
||||
#: src/guiPasswordChange.cpp:164
|
||||
#: src/guiPasswordChange.cpp:162
|
||||
msgid "Passwords do not match!"
|
||||
msgstr "¡Las contraseñas no coinciden!"
|
||||
|
||||
|
@ -1148,3 +963,210 @@ msgstr "PA1"
|
|||
#: src/keycode.cpp:249
|
||||
msgid "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 ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: minetest\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-02-14 23:12+0900\n"
|
||||
"PO-Revision-Date: 2015-02-22 10:57+0900\n"
|
||||
"POT-Creation-Date: 2013-11-23 17:37+0100\n"
|
||||
"PO-Revision-Date: 2014-12-28 15:48+0900\n"
|
||||
"Last-Translator: Rui Takeda <mrrst0914@gmail.com>\n"
|
||||
"Language-Team: Japanese <minetest_jp@m.add.ac>\n"
|
||||
"Language: ja\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 1.6.5\n"
|
||||
"Language: ja_JP\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
|
||||
msgid "Ok"
|
||||
msgstr "決定"
|
||||
msgid "Game Name"
|
||||
msgstr "ゲーム名"
|
||||
|
||||
msgid "World:"
|
||||
msgstr "ワールド:"
|
||||
|
||||
msgid "Hide Game"
|
||||
msgstr "ゲームを隠す"
|
||||
|
||||
msgid "Hide mp content"
|
||||
msgstr "Modパックの簡略化"
|
||||
|
||||
msgid "Mod:"
|
||||
msgstr "Mod名:"
|
||||
|
||||
msgid "Depends:"
|
||||
msgstr "依存Mod:"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
msgid "Create"
|
||||
msgstr "作成"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
msgid "Enable MP"
|
||||
msgstr "有効化"
|
||||
msgid "Gamemgr: Unable to copy mod \"$1\" to game \"$2\""
|
||||
msgstr "Gamemgr: \"$1\"のModを \"$2\" にコピーできません"
|
||||
|
||||
msgid "Disable MP"
|
||||
msgstr "無効化"
|
||||
msgid "Games"
|
||||
msgstr "ゲーム"
|
||||
|
||||
msgid "enabled"
|
||||
msgstr "有効化"
|
||||
msgid "Mods:"
|
||||
msgstr "Mod:"
|
||||
|
||||
msgid "Enable all"
|
||||
msgstr "すべて有効化"
|
||||
msgid "edit game"
|
||||
msgstr "ゲーム編集"
|
||||
|
||||
msgid "new game"
|
||||
msgstr "新規ゲーム"
|
||||
|
||||
msgid "Remove selected mod"
|
||||
msgstr "選択したModを削除"
|
||||
|
||||
msgid "Ok"
|
||||
msgstr "決定"
|
||||
|
||||
msgid "World name"
|
||||
msgstr "ワールド名"
|
||||
|
||||
msgid "Seed"
|
||||
msgstr "Seed値"
|
||||
msgstr "シード値"
|
||||
|
||||
msgid "Mapgen"
|
||||
msgstr "ワールドタイプ"
|
||||
msgstr "マップ生成"
|
||||
|
||||
msgid "Game"
|
||||
msgstr "ゲーム"
|
||||
|
||||
msgid "Create"
|
||||
msgstr "作成"
|
||||
|
||||
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 "Delete World \"$1\"?"
|
||||
msgstr "\"$1\"のワールドを削除しますか?"
|
||||
|
||||
msgid "Yes"
|
||||
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"
|
||||
msgstr "いいえ"
|
||||
|
||||
msgid "Rename Modpack:"
|
||||
msgstr "名前を変更"
|
||||
msgid "A world named \"$1\" already exists"
|
||||
msgstr "\"$1\"という名前のワールドを作成できません。同名のワールドが存在しています"
|
||||
|
||||
msgid "Accept"
|
||||
msgstr "決定"
|
||||
msgid "No worldname given or no game selected"
|
||||
msgstr "ワールド名が入力されていないか、ゲームが選択されていません"
|
||||
|
||||
msgid "Install Mod: file: \"$1\""
|
||||
msgstr "Modインストール:ファイル\"$1\"からModをインストールします。"
|
||||
msgid "To enable shaders the OpenGL driver needs to be used."
|
||||
msgstr "シェーダーを有効にするには、OpenGLのドライバが必要です"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
"Install Mod: unsupported filetype \"$1\" or broken archive"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modインストール:ファイル\"$1\"は非対応の形式か、壊れています。"
|
||||
msgid "Address/Port"
|
||||
msgstr "アドレス/ポート"
|
||||
|
||||
msgid "Failed to install $1 to $2"
|
||||
msgstr "$2へ$1をインストールできませんでした。"
|
||||
msgid "Name/Password"
|
||||
msgstr "名前/パスワード"
|
||||
|
||||
msgid "Install Mod: unable to find suitable foldername for modpack $1"
|
||||
msgstr ""
|
||||
"Modインストール:Modパック$1に適したフォルダ名を見つけることができませんでし"
|
||||
"た。"
|
||||
msgid "Public Serverlist"
|
||||
msgstr "公開されているサーバーリスト"
|
||||
|
||||
msgid "Install Mod: unable to find real modname for: $1"
|
||||
msgstr "Modインストール:$1の本来のMod名が不明です。"
|
||||
msgid "Delete"
|
||||
msgstr "削除"
|
||||
|
||||
msgid "Unsorted"
|
||||
msgstr "未分類"
|
||||
msgid "Connect"
|
||||
msgstr "接続"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "検索"
|
||||
msgid "New"
|
||||
msgstr "作成"
|
||||
|
||||
msgid "Downloading $1, please wait..."
|
||||
msgstr "$1をダウンロードしています。しばらくお待ちください..."
|
||||
msgid "Configure"
|
||||
msgstr "設定"
|
||||
|
||||
msgid "Successfully installed:"
|
||||
msgstr "インストールが完了しました。:"
|
||||
msgid "Start Game"
|
||||
msgstr "ゲームスタート"
|
||||
|
||||
msgid "Shortname:"
|
||||
msgstr "省略名"
|
||||
msgid "Select World:"
|
||||
msgstr "ワールド選択:"
|
||||
|
||||
msgid "Rating"
|
||||
msgstr "評価"
|
||||
msgid "Creative Mode"
|
||||
msgstr "クリエイティブモード"
|
||||
|
||||
msgid "re-Install"
|
||||
msgstr "再インストール"
|
||||
msgid "Enable Damage"
|
||||
msgstr "ダメージ有効"
|
||||
|
||||
msgid "Install"
|
||||
msgstr "インストール"
|
||||
msgid "Public"
|
||||
msgstr "公開する"
|
||||
|
||||
msgid "Close store"
|
||||
msgstr "閉じる"
|
||||
msgid "Name"
|
||||
msgstr "名前"
|
||||
|
||||
msgid "Page $1 of $2"
|
||||
msgstr "ページ $1/$2"
|
||||
msgid "Password"
|
||||
msgstr "パスワード"
|
||||
|
||||
msgid "Credits"
|
||||
msgstr "クレジット"
|
||||
msgid "Server Port"
|
||||
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"
|
||||
msgstr "開発者"
|
||||
|
||||
msgid "Active Contributors"
|
||||
msgstr "開発協力者"
|
||||
msgstr "貢献者"
|
||||
|
||||
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:"
|
||||
msgstr "インストール済みのMod:"
|
||||
|
||||
msgid "Online mod repository"
|
||||
msgstr "オンラインでModを検索"
|
||||
msgstr "オンラインで検索"
|
||||
|
||||
msgid "No mod description available"
|
||||
msgstr "Modの説明がありません。"
|
||||
msgstr "Modの説明がありません"
|
||||
|
||||
msgid "Mod information:"
|
||||
msgstr "Modの情報:"
|
||||
|
@ -193,376 +223,123 @@ msgstr "選択したModパックを削除"
|
|||
msgid "Uninstall selected mod"
|
||||
msgstr "選択したModを削除"
|
||||
|
||||
msgid "Select Mod File:"
|
||||
msgstr "Modファイルを選択"
|
||||
msgid "Rename Modpack:"
|
||||
msgstr "Modパックの名前を変更"
|
||||
|
||||
msgid "Mods"
|
||||
msgstr "Mod"
|
||||
msgid "Accept"
|
||||
msgstr "了承"
|
||||
|
||||
msgid "Address / Port :"
|
||||
msgstr "アドレスとポート:"
|
||||
msgid "World:"
|
||||
msgstr "ワールド:"
|
||||
|
||||
msgid "Name / Password :"
|
||||
msgstr "名前とパスワード:"
|
||||
msgid "Hide Game"
|
||||
msgstr "内部Mod"
|
||||
|
||||
msgid "Public Serverlist"
|
||||
msgstr "公開済みのサーバーの一覧"
|
||||
msgid "Hide mp content"
|
||||
msgstr "Modパックの簡略化"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "削除"
|
||||
msgid "Mod:"
|
||||
msgstr "Mod名:"
|
||||
|
||||
msgid "Connect"
|
||||
msgstr "接続"
|
||||
msgid "Depends:"
|
||||
msgstr "依存Mod:"
|
||||
|
||||
msgid "Creative mode"
|
||||
msgstr "クリエイティブモード"
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
msgid "Damage enabled"
|
||||
msgstr "HPあり"
|
||||
msgid "Enable MP"
|
||||
msgstr "有効化"
|
||||
|
||||
msgid "PvP enabled"
|
||||
msgstr "PvPあり"
|
||||
msgid "Disable MP"
|
||||
msgstr "無効化"
|
||||
|
||||
msgid "Client"
|
||||
msgstr "クライアント"
|
||||
msgid "enabled"
|
||||
msgstr "有効化"
|
||||
|
||||
msgid "New"
|
||||
msgstr "作成"
|
||||
msgid "Enable all"
|
||||
msgstr "全て有効化"
|
||||
|
||||
msgid "Configure"
|
||||
msgstr "設定"
|
||||
msgid "Modmgr: failed to delete \"$1\""
|
||||
msgstr "Modmgr: \"$1\"の削除に失敗しました"
|
||||
|
||||
msgid "Start Game"
|
||||
msgstr "ゲームスタート"
|
||||
msgid "Modmgr: invalid modpath \"$1\""
|
||||
msgstr "Modmgr: \"$1\"は無効なModパスです"
|
||||
|
||||
msgid "Select World:"
|
||||
msgstr "ワールドを選択:"
|
||||
msgid "Are you sure you want to delete \"$1\"?"
|
||||
msgstr "\"$1\"を削除してよろしいですか?"
|
||||
|
||||
msgid "Creative Mode"
|
||||
msgstr "クリエイティブモード"
|
||||
msgid "No of course not!"
|
||||
msgstr "違います!"
|
||||
|
||||
msgid "Enable Damage"
|
||||
msgstr "ダメージあり"
|
||||
msgid "Page $1 of $2"
|
||||
msgstr "ページ $1/$2"
|
||||
|
||||
msgid "Public"
|
||||
msgstr "サーバーを公開する"
|
||||
msgid "Rating"
|
||||
msgstr "評価"
|
||||
|
||||
msgid "Name/Password"
|
||||
msgstr "名前とパスワード"
|
||||
msgid "re-Install"
|
||||
msgstr "再インストール"
|
||||
|
||||
msgid "Bind Address"
|
||||
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 "Install"
|
||||
msgstr "インストール"
|
||||
|
||||
msgid "Item textures..."
|
||||
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 "終了中..."
|
||||
msgstr "アイテムのテクスチャ設定中..."
|
||||
|
||||
msgid "Loading..."
|
||||
msgstr "読み込み中..."
|
||||
msgstr "ロード中..."
|
||||
|
||||
msgid "Creating server..."
|
||||
msgstr "サーバー作成中..."
|
||||
msgstr "サーバー構築中..."
|
||||
|
||||
msgid "Creating client..."
|
||||
msgstr "クライアント作成中..."
|
||||
msgstr "クライアント作成中..."
|
||||
|
||||
msgid "Resolving address..."
|
||||
msgstr "アドレス解決中..."
|
||||
msgstr "アドレス解決中..."
|
||||
|
||||
msgid "Connecting to server..."
|
||||
msgstr "サーバー接続中..."
|
||||
msgstr "サーバー接続中..."
|
||||
|
||||
msgid "Item definitions..."
|
||||
msgstr "アイテム定義中..."
|
||||
msgstr "アイテム定義中..."
|
||||
|
||||
msgid "Node definitions..."
|
||||
msgstr "ノード定義中..."
|
||||
msgstr "ノード定義中..."
|
||||
|
||||
msgid "Media..."
|
||||
msgstr "..."
|
||||
|
||||
msgid " KB/s"
|
||||
msgstr " KB/秒"
|
||||
|
||||
msgid " MB/s"
|
||||
msgstr " MB/秒"
|
||||
msgid "Shutting down..."
|
||||
msgstr "終了中..."
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
"Check debug.txt for details."
|
||||
msgstr ""
|
||||
"\n"
|
||||
"詳細はdebug.txtをご覧ください。"
|
||||
"詳細はdebug.txtを御覧ください。"
|
||||
|
||||
msgid "Enter "
|
||||
msgstr "Enter"
|
||||
msgid "You died."
|
||||
msgstr "You died!"
|
||||
|
||||
msgid "ok"
|
||||
msgid "Respawn"
|
||||
msgstr "Respawn"
|
||||
|
||||
msgid "Proceed"
|
||||
msgstr "決定"
|
||||
|
||||
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
|
||||
msgstr "操作の設定を変更します。"
|
||||
msgstr "キーバインド"
|
||||
|
||||
msgid "\"Use\" = climb down"
|
||||
msgstr "「使用」で降りる"
|
||||
msgstr "「使う」キーで降りる"
|
||||
|
||||
msgid "Double tap \"jump\" to toggle fly"
|
||||
msgstr "「ジャンプ」二回押しで飛行モード"
|
||||
msgstr "ジャンプの二回押しで飛行"
|
||||
|
||||
msgid "Key already in use"
|
||||
msgstr "すでに使われているキーです。"
|
||||
msgstr "既に使われているキーです"
|
||||
|
||||
msgid "press key"
|
||||
msgstr "キー入力待ち"
|
||||
|
@ -574,19 +351,19 @@ msgid "Backward"
|
|||
msgstr "後退"
|
||||
|
||||
msgid "Left"
|
||||
msgstr "左に進む"
|
||||
msgstr "左へ進む"
|
||||
|
||||
msgid "Right"
|
||||
msgstr "右に進む"
|
||||
msgstr "右へ進む"
|
||||
|
||||
msgid "Use"
|
||||
msgstr "使用"
|
||||
msgstr "使う"
|
||||
|
||||
msgid "Jump"
|
||||
msgstr "ジャンプ"
|
||||
|
||||
msgid "Sneak"
|
||||
msgstr "スニーク"
|
||||
msgstr "こっそり進む"
|
||||
|
||||
msgid "Drop"
|
||||
msgstr "落とす"
|
||||
|
@ -604,16 +381,16 @@ msgid "Console"
|
|||
msgstr "コンソール"
|
||||
|
||||
msgid "Toggle fly"
|
||||
msgstr "飛行モード"
|
||||
msgstr "飛行"
|
||||
|
||||
msgid "Toggle fast"
|
||||
msgstr "高速移動モード"
|
||||
msgstr "高速移動"
|
||||
|
||||
msgid "Toggle noclip"
|
||||
msgstr "すり抜けモード"
|
||||
msgstr "すり抜け"
|
||||
|
||||
msgid "Range select"
|
||||
msgstr "視野範囲変更"
|
||||
msgstr "視野切り替え"
|
||||
|
||||
msgid "Print stacks"
|
||||
msgstr "スタックの表示"
|
||||
|
@ -631,13 +408,53 @@ msgid "Change"
|
|||
msgstr "変更"
|
||||
|
||||
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: "
|
||||
msgstr "音量:"
|
||||
msgstr "音量"
|
||||
|
||||
msgid "Exit"
|
||||
msgstr "閉じる"
|
||||
msgstr "戻る"
|
||||
|
||||
msgid "Left Button"
|
||||
msgstr "左ボタン"
|
||||
|
@ -854,3 +671,56 @@ msgstr "PA1"
|
|||
|
||||
msgid "Zoom"
|
||||
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}")
|
||||
|
||||
add_subdirectory(jthread)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(script)
|
||||
add_subdirectory(util)
|
||||
|
||||
set (unittests_SRCS
|
||||
test.cpp
|
||||
)
|
||||
|
||||
set(common_SRCS
|
||||
ban.cpp
|
||||
base64.cpp
|
||||
cavegen.cpp
|
||||
clientiface.cpp
|
||||
collision.cpp
|
||||
connection.cpp
|
||||
content_abm.cpp
|
||||
content_mapnode.cpp
|
||||
content_nodemeta.cpp
|
||||
|
@ -421,20 +418,20 @@ set(common_SRCS
|
|||
serverlist.cpp
|
||||
serverobject.cpp
|
||||
settings.cpp
|
||||
sha1.cpp
|
||||
socket.cpp
|
||||
sound.cpp
|
||||
staticobject.cpp
|
||||
subgame.cpp
|
||||
test.cpp
|
||||
tool.cpp
|
||||
treegen.cpp
|
||||
version.cpp
|
||||
voxel.cpp
|
||||
voxelalgorithms.cpp
|
||||
${common_network_SRCS}
|
||||
${JTHREAD_SRCS}
|
||||
${common_SCRIPT_SRCS}
|
||||
${UTIL_SRCS}
|
||||
${unittests_SRCS}
|
||||
)
|
||||
|
||||
# This gives us the icon and file version information
|
||||
|
@ -457,16 +454,9 @@ if(WIN32)
|
|||
endif()
|
||||
|
||||
# Client sources
|
||||
|
||||
if (BUILD_CLIENT)
|
||||
add_subdirectory(client)
|
||||
endif(BUILD_CLIENT)
|
||||
|
||||
set(minetest_SRCS
|
||||
${common_SRCS}
|
||||
${sound_SRCS}
|
||||
${client_SRCS}
|
||||
${client_network_SRCS}
|
||||
camera.cpp
|
||||
chat.cpp
|
||||
client.cpp
|
||||
|
@ -499,6 +489,7 @@ set(minetest_SRCS
|
|||
particles.cpp
|
||||
shader.cpp
|
||||
sky.cpp
|
||||
tile.cpp
|
||||
wieldmesh.cpp
|
||||
${minetest_SCRIPT_SRCS}
|
||||
)
|
||||
|
|
|
@ -23,22 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "irr_aabb3d.h"
|
||||
#include <string>
|
||||
|
||||
enum ActiveObjectType {
|
||||
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,
|
||||
};
|
||||
#define ACTIVEOBJECT_TYPE_INVALID 0
|
||||
// Other types are defined in content_object.h
|
||||
|
||||
struct ActiveObjectMessage
|
||||
|
@ -75,7 +60,7 @@ public:
|
|||
m_id = id;
|
||||
}
|
||||
|
||||
virtual ActiveObjectType getType() const = 0;
|
||||
virtual u8 getType() const = 0;
|
||||
virtual bool getCollisionBox(aabb3f *toset) = 0;
|
||||
virtual bool collideWithObjects() = 0;
|
||||
protected:
|
||||
|
|
|
@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "inventory.h"
|
||||
#include "mesh.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "util/numeric.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 "map.h"
|
||||
#include "mapgen.h"
|
||||
#include "mapgen_v5.h"
|
||||
#include "mapgen_v6.h"
|
||||
#include "mapgen_v7.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);
|
||||
|
||||
|
||||
///////////////////////////////////////// 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) {
|
||||
|
@ -398,68 +141,37 @@ void CaveV6::makeTunnel(bool dirswitch) {
|
|||
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;
|
||||
if (large_cave) {
|
||||
maxlen = v3s16(
|
||||
rs_part_max_length_rs,
|
||||
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
|
||||
rs * part_max_length_rs,
|
||||
ps->range(1, rs * part_max_length_rs),
|
||||
rs * part_max_length_rs
|
||||
);
|
||||
}
|
||||
|
||||
v3f vec(
|
||||
(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
|
||||
(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
|
||||
);
|
||||
|
||||
// Jump downward sometimes
|
||||
if (!large_cave && ps->range(0, 12) == 0) {
|
||||
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.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;
|
||||
|
||||
v3f rp = orp + vec;
|
||||
|
@ -567,12 +279,12 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
|
|||
|
||||
///////////////////////////////////////// Caves V7
|
||||
|
||||
|
||||
CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps) {
|
||||
CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
|
||||
this->mg = mg;
|
||||
this->vm = mg->vm;
|
||||
this->ndef = mg->ndef;
|
||||
this->water_level = mg->water_level;
|
||||
this->large_cave = is_large_cave;
|
||||
this->ps = ps;
|
||||
this->c_water_source = mg->c_water_source;
|
||||
this->c_lava_source = mg->c_lava_source;
|
||||
|
@ -582,10 +294,17 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps) {
|
|||
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));
|
||||
if (large_cave) {
|
||||
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));
|
||||
} 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);
|
||||
}
|
||||
|
@ -616,13 +335,15 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
|||
// 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;
|
||||
if (large_cave) {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
@ -639,7 +360,8 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
|||
|
||||
// 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;
|
||||
GenNotifyType notifytype = large_cave ?
|
||||
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
||||
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
);
|
||||
if (large_cave) {
|
||||
maxlen = v3s16(
|
||||
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;
|
||||
// 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
|
||||
);
|
||||
if (!large_cave && ps->range(0, 12) == 0) {
|
||||
vec = v3f(
|
||||
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 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.
|
||||
// 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;
|
||||
if (large_cave) {
|
||||
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 = 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->ridge_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
|
||||
}
|
||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
||||
s16 h = mg->ridge_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 = 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->ridge_heightmap[index];
|
||||
if (h < p.Y)
|
||||
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
|
||||
s16 h = mg->ridge_heightmap[index];
|
||||
if (h < p.Y)
|
||||
return;
|
||||
} else if (p.Y > water_level) {
|
||||
return;
|
||||
} else if (p.Y > water_level) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
|
||||
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
// Make large caves not so tall
|
||||
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)
|
||||
continue;
|
||||
|
||||
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
||||
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
||||
if (large_cave) {
|
||||
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_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
|
||||
|
||||
class MapgenV5;
|
||||
class MapgenV6;
|
||||
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 {
|
||||
public:
|
||||
MapgenV6 *mg;
|
||||
|
@ -129,6 +83,7 @@ public:
|
|||
int dswitchint;
|
||||
int part_max_length_rs;
|
||||
|
||||
bool large_cave;
|
||||
bool large_cave_is_flat;
|
||||
bool flooded;
|
||||
|
||||
|
@ -154,7 +109,7 @@ public:
|
|||
int water_level;
|
||||
|
||||
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 makeTunnel(bool dirswitch);
|
||||
void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine);
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
*/
|
||||
|
||||
#include <irrlicht.h>
|
||||
#include <iostream>
|
||||
#include "CGUITTFont.h"
|
||||
|
||||
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
|
||||
{
|
||||
// Make sure our casts to s32 in the loops below will not cause problems
|
||||
checkFontBitmapSize(bits);
|
||||
|
||||
// Determine what our texture size should be.
|
||||
// Add 1 because textures are inclusive-exclusive.
|
||||
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);
|
||||
u16* image_data = (u16*)image->lock();
|
||||
u8* glyph_data = bits.buffer;
|
||||
|
||||
for (s32 y = 0; y < (s32)bits.rows; ++y)
|
||||
for (int y = 0; y < bits.rows; ++y)
|
||||
{
|
||||
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.
|
||||
// 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);
|
||||
u32* image_data = (u32*)image->lock();
|
||||
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;
|
||||
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;
|
||||
//data[y * image_pitch + x] |= ((u32)(*bitsdata++) << 24);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define __BYTE_ORDER 0
|
||||
#define __LITTLE_ENDIAN 0
|
||||
#define __BIG_ENDIAN 1
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#elif __MACH__
|
||||
#include <machine/endian.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#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
|
||||
#define CLIENT_HEADER
|
||||
|
||||
#include "network/connection.h"
|
||||
#include "connection.h"
|
||||
#include "environment.h"
|
||||
#include "irrlichttypes_extrabloated.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 "hud.h"
|
||||
#include "particles.h"
|
||||
#include "network/networkpacket.h"
|
||||
|
||||
struct MeshMakeData;
|
||||
class MapBlockMesh;
|
||||
|
@ -48,6 +47,7 @@ struct MapDrawControl;
|
|||
class MtEventManager;
|
||||
struct PointedThing;
|
||||
class Database;
|
||||
class Server;
|
||||
|
||||
struct QueuedMeshUpdate
|
||||
{
|
||||
|
@ -341,61 +341,11 @@ public:
|
|||
*/
|
||||
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);
|
||||
|
||||
// Returns true if something was received
|
||||
bool AsyncProcessPacket();
|
||||
bool AsyncProcessData();
|
||||
void Send(NetworkPacket* pkt);
|
||||
void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||
|
||||
void interact(u8 action, const PointedThing& pointed);
|
||||
|
||||
|
@ -515,7 +465,7 @@ public:
|
|||
// Insert a media file appropriately into the appropriate manager
|
||||
bool loadMedia(const std::string &data, const std::string &filename);
|
||||
// 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
|
||||
void received_media();
|
||||
|
||||
|
@ -577,13 +527,13 @@ private:
|
|||
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
||||
//s32 m_daynight_i;
|
||||
//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
|
||||
u64 m_map_seed;
|
||||
std::string m_password;
|
||||
bool m_access_denied;
|
||||
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_nodedef_received;
|
||||
ClientMediaDownloader *m_media_downloader;
|
||||
|
@ -619,13 +569,12 @@ private:
|
|||
LocalClientState m_state;
|
||||
|
||||
// Used for saving server map to disk client-side
|
||||
Database *m_localdb;
|
||||
IntervalLimiter m_localdb_save_interval;
|
||||
u16 m_cache_save_interval;
|
||||
Database *localdb;
|
||||
Server *localserver;
|
||||
|
||||
// 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_enable_shaders;
|
||||
};
|
||||
|
||||
#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 "settings.h"
|
||||
#include "mapblock.h"
|
||||
#include "network/connection.h"
|
||||
#include "connection.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
#include "emerge.h"
|
||||
|
@ -59,7 +59,7 @@ void RemoteClient::ResendBlockIfOnWire(v3s16 p)
|
|||
}
|
||||
}
|
||||
|
||||
void RemoteClient::GetNextBlocks (
|
||||
void RemoteClient::GetNextBlocks(
|
||||
ServerEnvironment *env,
|
||||
EmergeManager * emerge,
|
||||
float dtime,
|
||||
|
@ -182,15 +182,18 @@ void RemoteClient::GetNextBlocks (
|
|||
//bool queue_is_full = false;
|
||||
|
||||
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"
|
||||
box
|
||||
*/
|
||||
std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
|
||||
std::list<v3s16> list;
|
||||
getFacePositions(list, d);
|
||||
|
||||
std::vector<v3s16>::iterator li;
|
||||
for(li = list.begin(); li != list.end(); ++li) {
|
||||
std::list<v3s16>::iterator li;
|
||||
for(li=list.begin(); li!=list.end(); ++li)
|
||||
{
|
||||
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);
|
||||
|
||||
for(std::map<u16, RemoteClient*>::iterator
|
||||
|
@ -596,22 +599,20 @@ void ClientInterface::UpdatePlayerList()
|
|||
{
|
||||
if (m_env != NULL)
|
||||
{
|
||||
std::vector<u16> clients = getClientIDs();
|
||||
std::list<u16> clients = getClientIDs();
|
||||
m_clients_names.clear();
|
||||
|
||||
|
||||
if(!clients.empty())
|
||||
infostream<<"Players:"<<std::endl;
|
||||
|
||||
for(std::vector<u16>::iterator
|
||||
for(std::list<u16>::iterator
|
||||
i = clients.begin();
|
||||
i != clients.end(); ++i) {
|
||||
i != clients.end(); ++i)
|
||||
{
|
||||
Player *player = m_env->getPlayer(*i);
|
||||
|
||||
if (player == NULL)
|
||||
if(player==NULL)
|
||||
continue;
|
||||
|
||||
infostream << "* " << player->getName() << "\t";
|
||||
infostream<<"* "<<player->getName()<<"\t";
|
||||
|
||||
{
|
||||
JMutexAutoLock clientslock(m_clients_mutex);
|
||||
|
@ -619,36 +620,32 @@ void ClientInterface::UpdatePlayerList()
|
|||
if(client != NULL)
|
||||
client->PrintInfo(infostream);
|
||||
}
|
||||
|
||||
m_clients_names.push_back(player->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInterface::send(u16 peer_id, u8 channelnum,
|
||||
NetworkPacket* pkt, bool reliable, bool deletepkt)
|
||||
void ClientInterface::send(u16 peer_id,u8 channelnum,
|
||||
SharedBuffer<u8> data, bool reliable)
|
||||
{
|
||||
m_con->Send(peer_id, channelnum, pkt, reliable);
|
||||
|
||||
if (deletepkt)
|
||||
delete pkt;
|
||||
m_con->Send(peer_id, channelnum, data, reliable);
|
||||
}
|
||||
|
||||
void ClientInterface::sendToAll(u16 channelnum,
|
||||
NetworkPacket* pkt, bool reliable)
|
||||
SharedBuffer<u8> data, bool reliable)
|
||||
{
|
||||
JMutexAutoLock clientslock(m_clients_mutex);
|
||||
for(std::map<u16, RemoteClient*>::iterator
|
||||
i = m_clients.begin();
|
||||
i != m_clients.end(); ++i) {
|
||||
i != m_clients.end(); ++i)
|
||||
{
|
||||
RemoteClient *client = i->second;
|
||||
|
||||
if (client->net_proto_version != 0) {
|
||||
m_con->Send(client->peer_id, channelnum, pkt, reliable);
|
||||
if (client->net_proto_version != 0)
|
||||
{
|
||||
m_con->Send(client->peer_id, channelnum, data, reliable);
|
||||
}
|
||||
}
|
||||
|
||||
delete pkt;
|
||||
}
|
||||
|
||||
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 "serialization.h" // for SER_FMT_VER_INVALID
|
||||
#include "jthread/jmutex.h"
|
||||
#include "network/networkpacket.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
@ -388,16 +387,16 @@ public:
|
|||
void step(float dtime);
|
||||
|
||||
/* 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 */
|
||||
std::vector<std::string> getPlayerNames();
|
||||
|
||||
/* 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 */
|
||||
void sendToAll(u16 channelnum, NetworkPacket* pkt, bool reliable);
|
||||
void sendToAll(u16 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||
|
||||
/* delete a client */
|
||||
void DeleteClient(u16 peer_id);
|
||||
|
@ -458,7 +457,7 @@ private:
|
|||
JMutex m_env_mutex;
|
||||
|
||||
float m_print_info_timer;
|
||||
|
||||
|
||||
static const char *statenames[];
|
||||
};
|
||||
|
||||
|
|
|
@ -161,9 +161,9 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
|
|||
else
|
||||
is_transparent = (f.solidness != 2);
|
||||
if(!is_transparent){
|
||||
if(count == needed_count)
|
||||
return true;
|
||||
count++;
|
||||
if(count >= needed_count)
|
||||
return true;
|
||||
}
|
||||
step *= stepfac;
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||
continue;
|
||||
}
|
||||
|
||||
MapBlockVect sectorblocks;
|
||||
std::list< MapBlock * > sectorblocks;
|
||||
sector->getBlocks(sectorblocks);
|
||||
|
||||
/*
|
||||
|
@ -256,8 +256,8 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||
|
||||
u32 sector_blocks_drawn = 0;
|
||||
|
||||
for(MapBlockVect::iterator i = sectorblocks.begin();
|
||||
i != sectorblocks.end(); i++)
|
||||
std::list< MapBlock * >::iterator i;
|
||||
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
||||
{
|
||||
MapBlock *block = *i;
|
||||
|
||||
|
@ -391,12 +391,12 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||
struct MeshBufList
|
||||
{
|
||||
video::SMaterial m;
|
||||
std::vector<scene::IMeshBuffer*> bufs;
|
||||
std::list<scene::IMeshBuffer*> bufs;
|
||||
};
|
||||
|
||||
struct MeshBufListList
|
||||
{
|
||||
std::vector<MeshBufList> lists;
|
||||
std::list<MeshBufList> lists;
|
||||
|
||||
void clear()
|
||||
{
|
||||
|
@ -405,7 +405,7 @@ struct MeshBufListList
|
|||
|
||||
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){
|
||||
MeshBufList &l = *i;
|
||||
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;
|
||||
for(std::vector<MeshBufList>::iterator i = lists.begin();
|
||||
i != lists.end(); ++i) {
|
||||
timecheck_counter++;
|
||||
if(timecheck_counter > 50) {
|
||||
timecheck_counter = 0;
|
||||
int time2 = time(0);
|
||||
if(time2 > time1 + 4) {
|
||||
infostream << "ClientMap::renderMap(): "
|
||||
"Rendering takes ages, returning."
|
||||
<< std::endl;
|
||||
return;
|
||||
for(std::list<MeshBufList>::iterator i = lists.begin();
|
||||
i != lists.end(); ++i)
|
||||
{
|
||||
{
|
||||
timecheck_counter++;
|
||||
if(timecheck_counter > 50)
|
||||
{
|
||||
timecheck_counter = 0;
|
||||
int time2 = time(0);
|
||||
if(time2 > time1 + 4)
|
||||
{
|
||||
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);
|
||||
|
||||
for(std::vector<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
|
||||
j != list.bufs.end(); ++j) {
|
||||
for(std::list<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
|
||||
j != list.bufs.end(); ++j)
|
||||
{
|
||||
scene::IMeshBuffer *buf = *j;
|
||||
driver->drawMeshBuffer(buf);
|
||||
vertex_count += buf->getVertexCount();
|
||||
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
|
||||
|
||||
|
|
|
@ -18,20 +18,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "clientmedia.h"
|
||||
#include "util/serialize.h"
|
||||
#include "util/string.h"
|
||||
#include "httpfetch.h"
|
||||
#include "client.h"
|
||||
#include "clientserver.h"
|
||||
#include "filecache.h"
|
||||
#include "filesys.h"
|
||||
#include "hex.h"
|
||||
#include "sha1.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include "porting.h"
|
||||
#include "settings.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()
|
||||
{
|
||||
|
@ -488,7 +488,7 @@ void ClientMediaDownloader::startConventionalTransfers(Client *client)
|
|||
if (m_uncached_received_count != m_uncached_count) {
|
||||
// Some media files have not been received yet, use the
|
||||
// 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
|
||||
it = m_files.begin();
|
||||
it != m_files.end(); ++it) {
|
||||
|
|
|
@ -39,13 +39,14 @@ ClientActiveObject::~ClientActiveObject()
|
|||
removeFromScene(true);
|
||||
}
|
||||
|
||||
ClientActiveObject* ClientActiveObject::create(ActiveObjectType type,
|
||||
IGameDef *gamedef, ClientEnvironment *env)
|
||||
ClientActiveObject* ClientActiveObject::create(u8 type, IGameDef *gamedef,
|
||||
ClientEnvironment *env)
|
||||
{
|
||||
// Find factory function
|
||||
std::map<u16, Factory>::iterator n;
|
||||
n = m_types.find(type);
|
||||
if(n == m_types.end()) {
|
||||
if(n == m_types.end())
|
||||
{
|
||||
// If factory is not found, just return.
|
||||
dstream<<"WARNING: ClientActiveObject: No factory for type="
|
||||
<<(int)type<<std::endl;
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
virtual void initialize(const std::string &data){}
|
||||
|
||||
// Create a certain type of ClientActiveObject
|
||||
static ClientActiveObject* create(ActiveObjectType type, IGameDef *gamedef,
|
||||
static ClientActiveObject* create(u8 type, IGameDef *gamedef,
|
||||
ClientEnvironment *env);
|
||||
|
||||
// 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.
|
||||
*/
|
||||
|
||||
#ifndef NETWORKPROTOCOL_HEADER
|
||||
#define NETWORKPROTOCOL_HEADER
|
||||
#ifndef CLIENTSERVER_HEADER
|
||||
#define CLIENTSERVER_HEADER
|
||||
#include "util/string.h"
|
||||
|
||||
/*
|
||||
|
@ -556,8 +556,6 @@ enum ToClientCommand
|
|||
v3f1000 first
|
||||
v3f1000 third
|
||||
*/
|
||||
|
||||
TOCLIENT_NUM_MSG_TYPES = 0x53,
|
||||
};
|
||||
|
||||
enum ToServerCommand
|
||||
|
@ -661,7 +659,7 @@ enum ToServerCommand
|
|||
|
||||
TOSERVER_INVENTORY_ACTION = 0x31,
|
||||
/*
|
||||
See InventoryAction in inventorymanager.h
|
||||
See InventoryAction in inventory.h
|
||||
*/
|
||||
|
||||
TOSERVER_CHAT_MESSAGE = 0x32,
|
||||
|
@ -797,8 +795,7 @@ enum ToServerCommand
|
|||
u16 len
|
||||
u8[len] full_version_string
|
||||
*/
|
||||
|
||||
TOSERVER_NUM_MSG_TYPES = 0x44,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -300,14 +300,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
/* add object boxes to cboxes */
|
||||
|
||||
|
||||
std::vector<ActiveObject*> objects;
|
||||
std::list<ActiveObject*> objects;
|
||||
#ifndef SERVER
|
||||
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
|
||||
if (c_env != 0) {
|
||||
if (c_env != 0)
|
||||
{
|
||||
f32 distance = speed_f.getLength();
|
||||
std::vector<DistanceSortedActiveObject> 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)) {
|
||||
objects.push_back((ActiveObject*)clientobjects[i].obj);
|
||||
}
|
||||
|
@ -317,10 +319,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
#endif
|
||||
{
|
||||
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
|
||||
if (s_env != 0) {
|
||||
if (s_env != 0)
|
||||
{
|
||||
f32 distance = speed_f.getLength();
|
||||
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);
|
||||
if ((self == 0) || (self != 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();
|
||||
iter != objects.end(); ++iter) {
|
||||
for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter)
|
||||
{
|
||||
ActiveObject *object = *iter;
|
||||
|
||||
if (object != NULL) {
|
||||
if (object != NULL)
|
||||
{
|
||||
aabb3f object_collisionbox;
|
||||
if (object->getCollisionBox(&object_collisionbox) &&
|
||||
object->collideWithObjects()) {
|
||||
object->collideWithObjects())
|
||||
{
|
||||
cboxes.push_back(object_collisionbox);
|
||||
is_unloaded.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 "exceptions.h"
|
||||
#include "constants.h"
|
||||
#include "network/networkpacket.h"
|
||||
#include "util/pointer.h"
|
||||
#include "util/container.h"
|
||||
#include "util/thread.h"
|
||||
|
@ -131,14 +130,14 @@ inline bool seqnum_higher(u16 totest, u16 base)
|
|||
{
|
||||
if (totest > base)
|
||||
{
|
||||
if ((totest - base) > (SEQNUM_MAX/2))
|
||||
if((totest - base) > (SEQNUM_MAX/2))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((base - totest) > (SEQNUM_MAX/2))
|
||||
if((base - totest) > (SEQNUM_MAX/2))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -363,9 +362,9 @@ public:
|
|||
packet is constructed. If not, returns one of length 0.
|
||||
*/
|
||||
SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
|
||||
|
||||
|
||||
void removeUnreliableTimedOuts(float dtime, float timeout);
|
||||
|
||||
|
||||
private:
|
||||
// Key is seqnum
|
||||
std::map<u16, IncomingSplitPacket*> m_buf;
|
||||
|
@ -496,7 +495,7 @@ public:
|
|||
|
||||
u16 readNextSplitSeqNum();
|
||||
void setNextSplitSeqNum(u16 seqnum);
|
||||
|
||||
|
||||
// This is for buffering the incoming packets that are coming in
|
||||
// the wrong order
|
||||
ReliablePacketBuffer incoming_reliables;
|
||||
|
@ -505,10 +504,10 @@ public:
|
|||
ReliablePacketBuffer outgoing_reliables_sent;
|
||||
|
||||
//queued reliable packets
|
||||
std::queue<BufferedPacket> queued_reliables;
|
||||
Queue<BufferedPacket> queued_reliables;
|
||||
|
||||
//queue commands prior splitting to packets
|
||||
std::queue<ConnectionCommand> queued_commands;
|
||||
Queue<ConnectionCommand> queued_commands;
|
||||
|
||||
IncomingSplitBuffer incoming_splits;
|
||||
|
||||
|
@ -874,7 +873,7 @@ struct ConnectionEvent
|
|||
|
||||
std::string describe()
|
||||
{
|
||||
switch(type) {
|
||||
switch(type){
|
||||
case CONNEVENT_NONE:
|
||||
return "CONNEVENT_NONE";
|
||||
case CONNEVENT_DATA_RECEIVED:
|
||||
|
@ -888,7 +887,7 @@ struct ConnectionEvent
|
|||
}
|
||||
return "Invalid ConnectionEvent";
|
||||
}
|
||||
|
||||
|
||||
void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
|
||||
{
|
||||
type = CONNEVENT_DATA_RECEIVED;
|
||||
|
@ -964,7 +963,7 @@ private:
|
|||
Connection* m_connection;
|
||||
unsigned int m_max_packet_size;
|
||||
float m_timeout;
|
||||
std::queue<OutgoingPacket> m_outgoing_queue;
|
||||
Queue<OutgoingPacket> m_outgoing_queue;
|
||||
JSemaphore m_send_sleep_semaphore;
|
||||
|
||||
unsigned int m_iteration_packets_avaialble;
|
||||
|
@ -1026,15 +1025,16 @@ public:
|
|||
ConnectionEvent getEvent();
|
||||
ConnectionEvent waitEvent(u32 timeout_ms);
|
||||
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 Connect(Address address);
|
||||
bool Connected();
|
||||
void Disconnect();
|
||||
u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
|
||||
void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
|
||||
u16 GetPeerID() { return m_peer_id; }
|
||||
void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||
void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
|
||||
u16 GetPeerID(){ return m_peer_id; }
|
||||
Address GetPeerAddress(u16 peer_id);
|
||||
float getPeerStat(u16 peer_id, rtt_stat_type type);
|
||||
float getLocalStat(rate_stat_type type);
|
||||
|
@ -1051,14 +1051,14 @@ protected:
|
|||
UDPPeer* createServerPeer(Address& sender);
|
||||
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 PrintInfo(std::ostream &out);
|
||||
void PrintInfo();
|
||||
|
||||
std::list<u16> getPeerIDs() { return m_peer_ids; }
|
||||
std::list<u16> getPeerIDs();
|
||||
|
||||
UDPSocket m_udpSocket;
|
||||
MutexedQueue<ConnectionCommand> m_command_queue;
|
||||
|
@ -1074,9 +1074,8 @@ private:
|
|||
|
||||
u16 m_peer_id;
|
||||
u32 m_protocol_id;
|
||||
|
||||
|
||||
std::map<u16, Peer*> m_peers;
|
||||
std::list<u16> m_peer_ids;
|
||||
JMutex m_peers_mutex;
|
||||
|
||||
ConnectionSendThread m_sendThread;
|
||||
|
@ -1096,3 +1095,4 @@ private:
|
|||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
@ -100,13 +100,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
/*
|
||||
GUI related things
|
||||
*/
|
||||
|
||||
// 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 TTF_DEFAULT_FONT_SIZE (14)
|
||||
#define DEFAULT_FONT_SIZE (10)
|
||||
|
||||
#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/serialize.h"
|
||||
#include "util/mathconstants.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "environment.h"
|
||||
#include "collision.h"
|
||||
#include "settings.h"
|
||||
#include "serialization.h" // For decompressZlib
|
||||
#include "gamedef.h"
|
||||
#include "clientobject.h"
|
||||
#include "content_object.h"
|
||||
#include "mesh.h"
|
||||
#include "itemdef.h"
|
||||
#include "tool.h"
|
||||
|
@ -144,7 +145,7 @@ public:
|
|||
TestCAO(IGameDef *gamedef, ClientEnvironment *env);
|
||||
virtual ~TestCAO();
|
||||
|
||||
ActiveObjectType getType() const
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_TEST;
|
||||
}
|
||||
|
@ -288,7 +289,7 @@ public:
|
|||
ItemCAO(IGameDef *gamedef, ClientEnvironment *env);
|
||||
virtual ~ItemCAO();
|
||||
|
||||
ActiveObjectType getType() const
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_ITEM;
|
||||
}
|
||||
|
@ -962,7 +963,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
|
|||
// Add a text node for showing the name
|
||||
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
|
||||
std::wstring wname = narrow_to_wide(m_name);
|
||||
m_textnode = smgr->addTextSceneNode(gui->getSkin()->getFont(),
|
||||
m_textnode = smgr->addTextSceneNode(gui->getBuiltInFont(),
|
||||
wname.c_str(), video::SColor(255,255,255,255), node);
|
||||
m_textnode->grab();
|
||||
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 "irrlichttypes_extrabloated.h"
|
||||
#include "content_object.h"
|
||||
#include "clientobject.h"
|
||||
#include "object_properties.h"
|
||||
#include "itemgroup.h"
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
return new GenericCAO(gamedef, env);
|
||||
}
|
||||
|
||||
inline ActiveObjectType getType() const
|
||||
inline u8 getType() const
|
||||
{
|
||||
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 <IBillboardSceneNode.h>
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "environment.h"
|
||||
#include "gamedef.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 "settings.h"
|
||||
#include "nodedef.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "mesh.h"
|
||||
#include <IMeshManipulator.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
|
||||
// for each face, that would be the same as passing NULL.
|
||||
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);
|
||||
|
||||
|
@ -54,7 +55,8 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
|||
|
||||
|
||||
|
||||
if(txc == NULL) {
|
||||
if(txc == NULL)
|
||||
{
|
||||
static const f32 txc_default[24] = {
|
||||
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};
|
||||
// Add to mesh collector
|
||||
for (s32 j = 0; j < 24; j += 4) {
|
||||
int tileindex = MYMIN(j / 4, tilecount - 1);
|
||||
collector->append(tiles[tileindex], vertices + j, 4, indices, 6);
|
||||
for(s32 j=0; j<24; j+=4)
|
||||
{
|
||||
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,
|
||||
MeshCollector &collector)
|
||||
{
|
||||
|
@ -191,6 +191,54 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
|
||||
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 y = 0; y < MAP_BLOCKSIZE; y++)
|
||||
for(s16 x = 0; x < MAP_BLOCKSIZE; x++)
|
||||
|
@ -1421,65 +1469,77 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
|
||||
content_t thiscontent = n.getContent();
|
||||
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
|
||||
&& ((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)
|
||||
is_rail_x[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_x_minus_y[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_x_plus_y[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_x[1] = true;
|
||||
|
||||
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)
|
||||
is_rail_x_minus_y[1] = true;
|
||||
|
||||
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)
|
||||
is_rail_x_plus_y[1] = true;
|
||||
|
||||
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)
|
||||
is_rail_z[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_z_minus_y[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_z_plus_y[0] = true;
|
||||
|
||||
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)
|
||||
is_rail_z[1] = true;
|
||||
|
||||
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)
|
||||
is_rail_z_minus_y[1] = true;
|
||||
|
||||
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)
|
||||
is_rail_z_plus_y[1] = true;
|
||||
|
||||
|
@ -1706,55 +1766,5 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
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.
|
||||
*/
|
||||
|
||||
#ifndef __GAME_PARAMS_H__
|
||||
#define __GAME_PARAMS_H__
|
||||
#ifndef CONTENT_OBJECT_HEADER
|
||||
#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 {
|
||||
u16 socket_port;
|
||||
std::string world_path;
|
||||
SubgameSpec game_spec;
|
||||
bool is_dedicated_server;
|
||||
int log_level;
|
||||
};
|
||||
#define ACTIVEOBJECT_TYPE_LUAENTITY 7
|
||||
|
||||
// Special type, not stored as a static object
|
||||
#define ACTIVEOBJECT_TYPE_PLAYER 100
|
||||
|
||||
// Special type, only exists as CAO
|
||||
#define ACTIVEOBJECT_TYPE_GENERIC 101
|
||||
|
||||
#endif
|
||||
|
|
@ -29,13 +29,60 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "tool.h" // For ToolCapabilities
|
||||
#include "gamedef.h"
|
||||
#include "player.h"
|
||||
#include "server.h"
|
||||
#include "scripting_game.h"
|
||||
#include "genericobject.h"
|
||||
#include "log.h"
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -50,7 +97,7 @@ public:
|
|||
{
|
||||
ServerActiveObject::registerType(getType(), create);
|
||||
}
|
||||
ActiveObjectType getType() const
|
||||
u8 getType() const
|
||||
{ return ACTIVEOBJECT_TYPE_TEST; }
|
||||
|
||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||
|
@ -91,7 +138,7 @@ public:
|
|||
data += itos(m_base_position.Z);
|
||||
|
||||
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)
|
||||
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
|
||||
*/
|
||||
|
@ -233,7 +477,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||
std::string str = getPropertyPacket();
|
||||
// create message and add to list
|
||||
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.
|
||||
|
@ -320,7 +564,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||
m_armor_groups);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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);
|
||||
// create message and add to list
|
||||
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);
|
||||
// create message and add to list
|
||||
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());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
if(getHP() == 0)
|
||||
|
@ -610,7 +854,7 @@ void LuaEntitySAO::setTextureMod(const std::string &mod)
|
|||
std::string str = gob_cmd_set_texture_mod(mod);
|
||||
// create message and add to list
|
||||
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,
|
||||
|
@ -624,7 +868,7 @@ void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
|
|||
);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
std::string LuaEntitySAO::getName()
|
||||
|
@ -664,7 +908,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
|||
);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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_sent(false),
|
||||
// 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_jump(1),
|
||||
m_physics_override_gravity(1),
|
||||
|
@ -856,7 +1105,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
|||
std::string str = getPropertyPacket();
|
||||
// create message and add to list
|
||||
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.
|
||||
|
@ -867,7 +1116,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
|||
m_attachment_position = v3f(0,0,0);
|
||||
m_attachment_rotation = v3f(0,0,0);
|
||||
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;
|
||||
|
@ -919,16 +1168,22 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
|||
);
|
||||
// create message and add to list
|
||||
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;
|
||||
std::string str = gob_cmd_update_armor_groups(
|
||||
m_armor_groups);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
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);
|
||||
// create message and add to list
|
||||
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);
|
||||
// create message and add to list
|
||||
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);
|
||||
// Movement caused by this command is always valid
|
||||
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)
|
||||
|
@ -992,19 +1248,22 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
|
|||
m_player->setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
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)
|
||||
{
|
||||
m_player->setYaw(yaw);
|
||||
((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id);
|
||||
// Force change on client
|
||||
m_moved = true;
|
||||
}
|
||||
|
||||
void PlayerSAO::setPitch(float 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,
|
||||
|
@ -1025,7 +1284,7 @@ int PlayerSAO::punch(v3f dir,
|
|||
std::string str = gob_cmd_punched(0, getHP());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push(aom);
|
||||
m_messages_out.push_back(aom);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1067,18 +1326,27 @@ void PlayerSAO::setHP(s16 hp)
|
|||
{
|
||||
s16 oldhp = m_player->hp;
|
||||
|
||||
if (hp < 0)
|
||||
if(hp < 0)
|
||||
hp = 0;
|
||||
else if (hp > PLAYER_MAX_HP)
|
||||
else if(hp > PLAYER_MAX_HP)
|
||||
hp = PLAYER_MAX_HP;
|
||||
|
||||
if(hp < oldhp && g_settings->getBool("enable_damage") == false)
|
||||
{
|
||||
m_hp_not_sent = true; // fix wrong prediction on client
|
||||
return;
|
||||
}
|
||||
|
||||
m_player->hp = hp;
|
||||
|
||||
if (oldhp > hp)
|
||||
m_damage += (oldhp - hp);
|
||||
if(hp != oldhp) {
|
||||
m_hp_not_sent = true;
|
||||
if(oldhp > hp)
|
||||
m_damage += oldhp - hp;
|
||||
}
|
||||
|
||||
// Update properties on death
|
||||
if ((hp == 0) != (oldhp == 0))
|
||||
if((hp == 0) != (oldhp == 0))
|
||||
m_properties_sent = false;
|
||||
}
|
||||
|
||||
|
@ -1157,6 +1425,11 @@ InventoryLocation PlayerSAO::getInventoryLocation() const
|
|||
return loc;
|
||||
}
|
||||
|
||||
void PlayerSAO::setInventoryModified()
|
||||
{
|
||||
m_inventory_not_sent = true;
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getWieldList() const
|
||||
{
|
||||
return "main";
|
||||
|
@ -1169,8 +1442,10 @@ int PlayerSAO::getWieldIndex() const
|
|||
|
||||
void PlayerSAO::setWieldIndex(int i)
|
||||
{
|
||||
if(i != m_wield_index) {
|
||||
if(i != m_wield_index)
|
||||
{
|
||||
m_wield_index = i;
|
||||
m_wielded_item_not_sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1237,6 +1512,7 @@ bool PlayerSAO::checkMovementCheat()
|
|||
<<" moved too fast; resetting position"
|
||||
<<std::endl;
|
||||
m_player->setPosition(m_last_good_position);
|
||||
m_moved = true;
|
||||
cheated = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define CONTENT_SAO_HEADER
|
||||
|
||||
#include "serverobject.h"
|
||||
#include "content_object.h"
|
||||
#include "itemgroup.h"
|
||||
#include "player.h"
|
||||
#include "object_properties.h"
|
||||
|
||||
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
|
||||
const std::string &itemstring);
|
||||
|
||||
/*
|
||||
LuaEntitySAO needs some internals exposed.
|
||||
*/
|
||||
|
@ -35,9 +39,9 @@ public:
|
|||
LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||
const std::string &name, const std::string &state);
|
||||
~LuaEntitySAO();
|
||||
ActiveObjectType getType() const
|
||||
u8 getType() const
|
||||
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
|
||||
ActiveObjectType getSendType() const
|
||||
u8 getSendType() const
|
||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||
virtual void addedToEnvironment(u32 dtime_s);
|
||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||
|
@ -154,9 +158,9 @@ public:
|
|||
PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
||||
const std::set<std::string> &privs, bool is_singleplayer);
|
||||
~PlayerSAO();
|
||||
ActiveObjectType getType() const
|
||||
u8 getType() const
|
||||
{ return ACTIVEOBJECT_TYPE_PLAYER; }
|
||||
ActiveObjectType getSendType() const
|
||||
u8 getSendType() const
|
||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||
std::string getDescription();
|
||||
|
||||
|
@ -205,6 +209,7 @@ public:
|
|||
Inventory* getInventory();
|
||||
const Inventory* getInventory() const;
|
||||
InventoryLocation getInventoryLocation() const;
|
||||
void setInventoryModified();
|
||||
std::string getWieldList() const;
|
||||
int getWieldIndex() const;
|
||||
void setWieldIndex(int i);
|
||||
|
@ -314,6 +319,13 @@ private:
|
|||
bool m_attachment_sent;
|
||||
|
||||
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_jump;
|
||||
float m_physics_override_gravity;
|
||||
|
|
|
@ -418,28 +418,27 @@ bool CraftDefinitionShaped::check(const CraftInput &input, IGameDef *gamedef) co
|
|||
return false; // it was empty
|
||||
|
||||
// Different sizes?
|
||||
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)
|
||||
if(inp_max_x - inp_min_x != rec_max_x - rec_min_x)
|
||||
return false;
|
||||
if(inp_max_y - inp_min_y != rec_max_y - rec_min_y)
|
||||
return false;
|
||||
|
||||
// Verify that all item names in the bounding box are equal
|
||||
unsigned int w = inp_max_x - inp_min_x + 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++) {
|
||||
unsigned int inp_y = (inp_min_y + y) * inp_width;
|
||||
unsigned int rec_y = (rec_min_y + y) * rec_width;
|
||||
|
||||
for(unsigned int x=0; x < w; x++) {
|
||||
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;
|
||||
}
|
||||
if(!inputItemMatchesRecipe(
|
||||
inp_names[inp_y * inp_width + inp_x],
|
||||
rec_names[rec_y * rec_width + 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 "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;
|
||||
}
|
||||
|
||||
std::string Database_Dummy::loadBlock(const v3s16 &pos)
|
||||
std::string Database_Dummy::loadBlock(v3s16 blockpos)
|
||||
{
|
||||
s64 i = getBlockAsInteger(pos);
|
||||
if (m_database.count(i))
|
||||
return m_database[i];
|
||||
if (m_database.count(getBlockAsInteger(blockpos)))
|
||||
return m_database[getBlockAsInteger(blockpos)];
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
x != m_database.end(); ++x) {
|
||||
dst.push_back(getIntegerAsBlock(x->first));
|
||||
for(std::map<u64, std::string>::iterator x = m_database.begin(); x != m_database.end(); ++x)
|
||||
{
|
||||
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 "irrlichttypes.h"
|
||||
|
||||
class ServerMap;
|
||||
|
||||
class Database_Dummy : public Database
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
Database_Dummy(ServerMap *map);
|
||||
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_Dummy();
|
||||
private:
|
||||
std::map<s64, std::string> m_database;
|
||||
ServerMap *srvmap;
|
||||
std::map<u64, std::string> m_database;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,54 +22,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#if USE_LEVELDB
|
||||
|
||||
#include "database-leveldb.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
#include "exceptions.h"
|
||||
#include "util/string.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) \
|
||||
if (!(s).ok()) { \
|
||||
throw FileNotGoodException(std::string("LevelDB error: ") + \
|
||||
(s).ToString()); \
|
||||
throw FileNotGoodException(std::string("LevelDB error: ") + (s).ToString()); \
|
||||
}
|
||||
|
||||
|
||||
Database_LevelDB::Database_LevelDB(const std::string &savedir)
|
||||
Database_LevelDB::Database_LevelDB(ServerMap *map, std::string savedir)
|
||||
{
|
||||
leveldb::Options options;
|
||||
options.create_if_missing = true;
|
||||
leveldb::Status status = leveldb::DB::Open(options,
|
||||
savedir + DIR_DELIM + "map.db", &m_database);
|
||||
leveldb::Status status = leveldb::DB::Open(options, savedir + DIR_DELIM + "map.db", &m_database);
|
||||
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(),
|
||||
i64tos(getBlockAsInteger(pos)), data);
|
||||
i64tos(getBlockAsInteger(blockpos)), data);
|
||||
if (!status.ok()) {
|
||||
errorstream << "WARNING: saveBlock: LevelDB error saving block "
|
||||
<< PP(pos) << ": " << status.ToString() << std::endl;
|
||||
<< PP(blockpos) << ": " << status.ToString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Database_LevelDB::loadBlock(const v3s16 &pos)
|
||||
std::string Database_LevelDB::loadBlock(v3s16 blockpos)
|
||||
{
|
||||
std::string datastr;
|
||||
leveldb::Status status = m_database->Get(leveldb::ReadOptions(),
|
||||
i64tos(getBlockAsInteger(pos)), &datastr);
|
||||
i64tos(getBlockAsInteger(blockpos)), &datastr);
|
||||
|
||||
if(status.ok())
|
||||
return datastr;
|
||||
|
@ -77,20 +80,20 @@ std::string Database_LevelDB::loadBlock(const v3s16 &pos)
|
|||
return "";
|
||||
}
|
||||
|
||||
bool Database_LevelDB::deleteBlock(const v3s16 &pos)
|
||||
bool Database_LevelDB::deleteBlock(v3s16 blockpos)
|
||||
{
|
||||
leveldb::Status status = m_database->Delete(leveldb::WriteOptions(),
|
||||
i64tos(getBlockAsInteger(pos)));
|
||||
i64tos(getBlockAsInteger(blockpos)));
|
||||
if (!status.ok()) {
|
||||
errorstream << "WARNING: deleteBlock: LevelDB error deleting block "
|
||||
<< PP(pos) << ": " << status.ToString() << std::endl;
|
||||
<< PP(blockpos) << ": " << status.ToString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
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());
|
||||
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
||||
|
@ -100,5 +103,8 @@ void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
|||
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 <string>
|
||||
|
||||
class ServerMap;
|
||||
|
||||
class Database_LevelDB : public Database
|
||||
{
|
||||
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();
|
||||
|
||||
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:
|
||||
leveldb::DB *m_database;
|
||||
ServerMap *srvmap;
|
||||
leveldb::DB* m_database;
|
||||
};
|
||||
|
||||
#endif // USE_LEVELDB
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,78 +20,84 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "config.h"
|
||||
|
||||
#if USE_REDIS
|
||||
/*
|
||||
Redis databases
|
||||
*/
|
||||
|
||||
|
||||
#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 "log.h"
|
||||
#include "exceptions.h"
|
||||
#include "util/string.h"
|
||||
|
||||
#include <hiredis.h>
|
||||
#include <cassert>
|
||||
#include "filesys.h"
|
||||
|
||||
|
||||
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;
|
||||
try {
|
||||
tmp = conf.get("redis_address");
|
||||
hash = conf.get("redis_hash");
|
||||
} catch (SettingNotFoundException) {
|
||||
throw SettingNotFoundException("Set redis_address and "
|
||||
"redis_hash in world.mt to use the redis backend");
|
||||
tmp = conf.get("redis_address");
|
||||
hash = conf.get("redis_hash");
|
||||
} catch(SettingNotFoundException e) {
|
||||
throw SettingNotFoundException("Set redis_address and redis_hash in world.mt to use the redis backend");
|
||||
}
|
||||
const char *addr = tmp.c_str();
|
||||
int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379;
|
||||
ctx = redisConnect(addr, port);
|
||||
if (!ctx) {
|
||||
if(!ctx)
|
||||
throw FileNotGoodException("Cannot allocate redis context");
|
||||
} else if(ctx->err) {
|
||||
else if(ctx->err) {
|
||||
std::string err = std::string("Connection error: ") + ctx->errstr;
|
||||
redisFree(ctx);
|
||||
throw FileNotGoodException(err);
|
||||
}
|
||||
srvmap = map;
|
||||
}
|
||||
|
||||
Database_Redis::~Database_Redis()
|
||||
int Database_Redis::Initialized(void)
|
||||
{
|
||||
redisFree(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Database_Redis::beginSave() {
|
||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "MULTI"));
|
||||
if (!reply) {
|
||||
throw FileNotGoodException(std::string(
|
||||
"Redis command 'MULTI' failed: ") + ctx->errstr);
|
||||
}
|
||||
redisReply *reply;
|
||||
reply = (redisReply*) redisCommand(ctx, "MULTI");
|
||||
if(!reply)
|
||||
throw FileNotGoodException(std::string("redis command 'MULTI' failed: ") + ctx->errstr);
|
||||
freeReplyObject(reply);
|
||||
}
|
||||
|
||||
void Database_Redis::endSave() {
|
||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "EXEC"));
|
||||
if (!reply) {
|
||||
throw FileNotGoodException(std::string(
|
||||
"Redis command 'EXEC' failed: ") + ctx->errstr);
|
||||
}
|
||||
redisReply *reply;
|
||||
reply = (redisReply*) redisCommand(ctx, "EXEC");
|
||||
if(!reply)
|
||||
throw FileNotGoodException(std::string("redis command 'EXEC' failed: ") + ctx->errstr);
|
||||
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",
|
||||
hash.c_str(), tmp.c_str(), data.c_str(), data.size()));
|
||||
redisReply *reply = (redisReply *)redisCommand(ctx, "HSET %s %s %b",
|
||||
hash.c_str(), tmp.c_str(), data.c_str(), data.size());
|
||||
if (!reply) {
|
||||
errorstream << "WARNING: saveBlock: redis command 'HSET' failed on "
|
||||
"block " << PP(pos) << ": " << ctx->errstr << std::endl;
|
||||
"block " << PP(blockpos) << ": " << ctx->errstr << std::endl;
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
errorstream << "WARNING: saveBlock: saving block " << PP(pos)
|
||||
errorstream << "WARNING: saveBlock: saving block " << PP(blockpos)
|
||||
<< "failed" << std::endl;
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
|
@ -101,36 +107,38 @@ bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string Database_Redis::loadBlock(const v3s16 &pos)
|
||||
std::string Database_Redis::loadBlock(v3s16 blockpos)
|
||||
{
|
||||
std::string tmp = i64tos(getBlockAsInteger(pos));
|
||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx,
|
||||
"HGET %s %s", hash.c_str(), tmp.c_str()));
|
||||
std::string tmp = i64tos(getBlockAsInteger(blockpos));
|
||||
redisReply *reply;
|
||||
reply = (redisReply*) redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str());
|
||||
|
||||
if (!reply) {
|
||||
throw FileNotGoodException(std::string(
|
||||
"Redis command 'HGET %s %s' failed: ") + ctx->errstr);
|
||||
} else if (reply->type != REDIS_REPLY_STRING) {
|
||||
if(!reply)
|
||||
throw FileNotGoodException(std::string("redis command 'HGET %s %s' failed: ") + ctx->errstr);
|
||||
if(reply->type != REDIS_REPLY_STRING)
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string str(reply->str, reply->len);
|
||||
freeReplyObject(reply); // std::string copies the memory so this won't cause any problems
|
||||
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,
|
||||
"HDEL %s %s", hash.c_str(), tmp.c_str()));
|
||||
redisReply *reply = (redisReply *)redisCommand(ctx, "HDEL %s %s",
|
||||
hash.c_str(), tmp.c_str());
|
||||
if (!reply) {
|
||||
throw FileNotGoodException(std::string(
|
||||
"Redis command 'HDEL %s %s' failed: ") + ctx->errstr);
|
||||
} else if (reply->type == REDIS_REPLY_ERROR) {
|
||||
errorstream << "WARNING: deleteBlock: deleting block " << PP(pos)
|
||||
<< " failed" << std::endl;
|
||||
errorstream << "WARNING: deleteBlock: redis command 'HDEL' failed on "
|
||||
"block " << PP(blockpos) << ": " << ctx->errstr << std::endl;
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
errorstream << "WARNING: deleteBlock: deleting block " << PP(blockpos)
|
||||
<< "failed" << std::endl;
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
@ -139,21 +147,24 @@ bool Database_Redis::deleteBlock(const v3s16 &pos)
|
|||
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()));
|
||||
if (!reply) {
|
||||
throw FileNotGoodException(std::string(
|
||||
"Redis command 'HKEYS %s' failed: ") + ctx->errstr);
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
redisReply *reply;
|
||||
reply = (redisReply*) redisCommand(ctx, "HKEYS %s", hash.c_str());
|
||||
if(!reply)
|
||||
throw FileNotGoodException(std::string("redis command 'HKEYS %s' failed: ") + ctx->errstr);
|
||||
if(reply->type != REDIS_REPLY_ARRAY)
|
||||
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);
|
||||
dst.push_back(getIntegerAsBlock(stoi64(reply->element[i]->str)));
|
||||
}
|
||||
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 <string>
|
||||
|
||||
class Settings;
|
||||
class ServerMap;
|
||||
|
||||
class Database_Redis : public Database
|
||||
{
|
||||
public:
|
||||
Database_Redis(Settings &conf);
|
||||
~Database_Redis();
|
||||
|
||||
Database_Redis(ServerMap *map, std::string savedir);
|
||||
virtual void beginSave();
|
||||
virtual void endSave();
|
||||
|
||||
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);
|
||||
|
||||
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_Redis();
|
||||
private:
|
||||
ServerMap *srvmap;
|
||||
redisContext *ctx;
|
||||
std::string hash;
|
||||
};
|
||||
|
||||
#endif // USE_REDIS
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,231 +18,297 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
/*
|
||||
SQLite format specification:
|
||||
blocks:
|
||||
(PK) INT id
|
||||
BLOB data
|
||||
SQLite format specification:
|
||||
- Initially only replaces sectors/ and sectors2/
|
||||
|
||||
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 "log.h"
|
||||
#include "filesys.h"
|
||||
#include "exceptions.h"
|
||||
#include "map.h"
|
||||
#include "mapsector.h"
|
||||
#include "mapblock.h"
|
||||
#include "serialization.h"
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "util/string.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
#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)
|
||||
Database_SQLite3::Database_SQLite3(ServerMap *map, std::string savedir)
|
||||
{
|
||||
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() {
|
||||
verifyDatabase();
|
||||
SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE);
|
||||
sqlite3_reset(m_stmt_begin);
|
||||
if(sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK)
|
||||
errorstream<<"WARNING: beginSave() failed, saving might be slow.";
|
||||
}
|
||||
|
||||
void Database_SQLite3::endSave() {
|
||||
verifyDatabase();
|
||||
SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE);
|
||||
sqlite3_reset(m_stmt_end);
|
||||
if(sqlite3_exec(m_database, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK)
|
||||
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
|
||||
|
||||
if (!fs::CreateAllDirs(m_savedir)) {
|
||||
infostream << "Database_SQLite3: Failed to create directory \""
|
||||
<< m_savedir << "\"" << std::endl;
|
||||
throw FileNotGoodException("Failed to create database "
|
||||
"save directory");
|
||||
}
|
||||
createDirs(m_savedir); // ?
|
||||
|
||||
bool needs_create = !fs::PathExists(dbp);
|
||||
if(!fs::PathExists(dbp))
|
||||
needs_create = true;
|
||||
|
||||
if (sqlite3_open_v2(dbp.c_str(), &m_database,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
NULL) != SQLITE_OK) {
|
||||
errorstream << "SQLite3 database failed to open: "
|
||||
<< sqlite3_errmsg(m_database) << std::endl;
|
||||
d = sqlite3_open_v2(dbp.c_str(), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
if(d != SQLITE_OK) {
|
||||
errorstream<<"SQLite3 database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||
throw FileNotGoodException("Cannot open database file");
|
||||
}
|
||||
|
||||
if (needs_create) {
|
||||
if(needs_create)
|
||||
createDatabase();
|
||||
}
|
||||
|
||||
std::string query_str = std::string("PRAGMA synchronous = ")
|
||||
std::string querystr = std::string("PRAGMA synchronous = ")
|
||||
+ itos(g_settings->getU16("sqlite_synchronous"));
|
||||
SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL));
|
||||
}
|
||||
|
||||
void Database_SQLite3::verifyDatabase()
|
||||
{
|
||||
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;
|
||||
d = sqlite3_exec(m_database, querystr.c_str(), NULL, NULL, NULL);
|
||||
if(d != SQLITE_OK) {
|
||||
errorstream<<"Database pragma set failed: "
|
||||
<<sqlite3_errmsg(m_database)<<std::endl;
|
||||
throw FileNotGoodException("Cannot set pragma");
|
||||
}
|
||||
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();
|
||||
|
||||
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__
|
||||
/**
|
||||
* Note: For some unknown reason SQLite3 fails to REPLACE blocks on Android,
|
||||
* deleting them and then inserting works.
|
||||
* Note: For some unknown reason sqlite3 fails to REPLACE blocks on android,
|
||||
* deleting them and inserting first works.
|
||||
*/
|
||||
bindPos(m_stmt_read, pos);
|
||||
|
||||
if (sqlite3_step(m_stmt_read) == SQLITE_ROW) {
|
||||
deleteBlock(pos);
|
||||
if (sqlite3_bind_int64(m_database_read, 1, bkey) != SQLITE_OK) {
|
||||
infostream << "WARNING: Could not bind block position for load: "
|
||||
<< sqlite3_errmsg(m_database)<<std::endl;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
bindPos(m_stmt_write, pos);
|
||||
SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL));
|
||||
if (sqlite3_bind_int64(m_database_write, 1, bkey) != SQLITE_OK) {
|
||||
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)
|
||||
sqlite3_reset(m_stmt_write);
|
||||
if (sqlite3_bind_blob(m_database_write, 2, (void *)data.c_str(),
|
||||
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;
|
||||
}
|
||||
|
||||
std::string Database_SQLite3::loadBlock(const v3s16 &pos)
|
||||
std::string Database_SQLite3::loadBlock(v3s16 blockpos)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
bindPos(m_stmt_read, pos);
|
||||
|
||||
if (sqlite3_step(m_stmt_read) != SQLITE_ROW) {
|
||||
sqlite3_reset(m_stmt_read);
|
||||
return "";
|
||||
if (sqlite3_bind_int64(m_database_read, 1, getBlockAsInteger(blockpos)) != SQLITE_OK) {
|
||||
errorstream << "Could not bind block position for load: "
|
||||
<< sqlite3_errmsg(m_database)<<std::endl;
|
||||
}
|
||||
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 (data)
|
||||
s = std::string(data, len);
|
||||
if (sqlite3_step(m_database_read) == SQLITE_ROW) {
|
||||
const char *data = (const char *) sqlite3_column_blob(m_database_read, 0);
|
||||
size_t len = sqlite3_column_bytes(m_database_read, 0);
|
||||
|
||||
sqlite3_step(m_stmt_read);
|
||||
// We should never get more than 1 row, so ok to reset
|
||||
sqlite3_reset(m_stmt_read);
|
||||
std::string s = "";
|
||||
if(data)
|
||||
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()
|
||||
{
|
||||
int e;
|
||||
assert(m_database);
|
||||
SQLOK(sqlite3_exec(m_database,
|
||||
"CREATE TABLE IF NOT EXISTS `blocks` (\n"
|
||||
" `pos` INT PRIMARY KEY,\n"
|
||||
" `data` BLOB\n"
|
||||
");\n",
|
||||
NULL, NULL, NULL));
|
||||
e = sqlite3_exec(m_database,
|
||||
"CREATE TABLE IF NOT EXISTS `blocks` ("
|
||||
"`pos` INT NOT NULL PRIMARY KEY,"
|
||||
"`data` BLOB"
|
||||
");"
|
||||
, 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();
|
||||
|
||||
while (sqlite3_step(m_stmt_list) == SQLITE_ROW) {
|
||||
dst.push_back(getIntegerAsBlock(sqlite3_column_int64(m_stmt_list, 0)));
|
||||
while(sqlite3_step(m_database_list) == SQLITE_ROW)
|
||||
{
|
||||
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()
|
||||
{
|
||||
FINALIZE_STATEMENT(m_stmt_read)
|
||||
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)
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
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(): "
|
||||
<< "Failed to close database: "
|
||||
<< sqlite3_errmsg(m_database) << std::endl;
|
||||
<< "Failed to close database: rc=" << rc << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,43 +27,35 @@ extern "C" {
|
|||
#include "sqlite3.h"
|
||||
}
|
||||
|
||||
class ServerMap;
|
||||
|
||||
class Database_SQLite3 : public Database
|
||||
{
|
||||
public:
|
||||
Database_SQLite3(const std::string &savedir);
|
||||
|
||||
Database_SQLite3(ServerMap *map, std::string savedir);
|
||||
virtual void beginSave();
|
||||
virtual void endSave();
|
||||
|
||||
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);
|
||||
virtual bool initialized() const { return m_initialized; }
|
||||
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_SQLite3();
|
||||
|
||||
private:
|
||||
// Open the database
|
||||
void openDatabase();
|
||||
ServerMap *srvmap;
|
||||
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
|
||||
void createDatabase();
|
||||
// Open and initialize the database if needed
|
||||
// Verify we can read/write to the database
|
||||
void verifyDatabase();
|
||||
|
||||
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;
|
||||
void createDirs(std::string path);
|
||||
};
|
||||
|
||||
#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 +
|
||||
(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;
|
||||
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
|
||||
#define DATABASE_HEADER
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "irr_v3d.h"
|
||||
#include "irrlichttypes.h"
|
||||
|
@ -32,22 +32,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
class Database
|
||||
{
|
||||
public:
|
||||
virtual ~Database() {}
|
||||
virtual void beginSave() = 0;
|
||||
virtual void endSave() = 0;
|
||||
|
||||
virtual void beginSave() {}
|
||||
virtual void endSave() {}
|
||||
|
||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data) = 0;
|
||||
virtual std::string loadBlock(const v3s16 &pos) = 0;
|
||||
virtual bool deleteBlock(const v3s16 &pos) = 0;
|
||||
|
||||
static s64 getBlockAsInteger(const v3s16 &pos);
|
||||
static v3s16 getIntegerAsBlock(s64 i);
|
||||
|
||||
virtual void listAllLoadableBlocks(std::vector<v3s16> &dst) = 0;
|
||||
|
||||
virtual bool initialized() const { return true; }
|
||||
virtual bool saveBlock(v3s16 blockpos, std::string &data) = 0;
|
||||
virtual std::string loadBlock(v3s16 blockpos) = 0;
|
||||
virtual bool deleteBlock(v3s16 blockpos) = 0;
|
||||
s64 getBlockAsInteger(const v3s16 pos) const;
|
||||
v3s16 getIntegerAsBlock(s64 i) const;
|
||||
virtual void listAllLoadableBlocks(std::list<v3s16> &dst) = 0;
|
||||
virtual int Initialized(void)=0;
|
||||
virtual ~Database() {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("keymap_freemove", "KEY_KEY_K");
|
||||
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
|
||||
settings->setDefault("keymap_noclip", "KEY_KEY_H");
|
||||
settings->setDefault("keymap_cinematic", "KEY_F8");
|
||||
settings->setDefault("keymap_screenshot", "KEY_F12");
|
||||
settings->setDefault("keymap_toggle_hud", "KEY_F1");
|
||||
settings->setDefault("keymap_toggle_chat", "KEY_F2");
|
||||
|
@ -116,9 +115,6 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("free_move", "false");
|
||||
settings->setDefault("noclip", "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("invert_mouse", "false");
|
||||
settings->setDefault("enable_clouds", "true");
|
||||
|
@ -292,7 +288,6 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("water_level", "1");
|
||||
settings->setDefault("chunksize", "5");
|
||||
settings->setDefault("mg_flags", "");
|
||||
settings->setDefault("enable_floating_dungeons", "true");
|
||||
|
||||
// IPv6
|
||||
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
|
||||
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
||||
|
||||
bool no_float = !g_settings->getBool("enable_floating_dungeons");
|
||||
|
||||
// Set all air and water (and optionally ignore) to be untouchable
|
||||
// to make dungeons open to caves and open air
|
||||
// Set all air and water to be untouchable to make dungeons open
|
||||
// to caves and open air
|
||||
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
||||
for (s16 y = nmin.Y; y <= nmax.Y; y++) {
|
||||
u32 i = vm->m_area.index(nmin.X, y, z);
|
||||
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
if (c == CONTENT_AIR || c == dp.c_water
|
||||
|| (no_float && c == CONTENT_IGNORE))
|
||||
if (c == CONTENT_AIR || c == dp.c_water)
|
||||
vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -361,10 +361,7 @@ void EmergeManager::loadParamsFromSettings(Settings *settings)
|
|||
std::string seed_str;
|
||||
const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed";
|
||||
|
||||
if (!settings->getNoEx("seed", seed_str)) {
|
||||
g_settings->getNoEx(setname, seed_str);
|
||||
}
|
||||
if (!seed_str.empty()) {
|
||||
if (settings->getNoEx(setname, seed_str) && !seed_str.empty()) {
|
||||
params.seed = read_seed(seed_str.c_str());
|
||||
} else {
|
||||
params.seed =
|
||||
|
|
|
@ -61,8 +61,9 @@ Environment::Environment():
|
|||
Environment::~Environment()
|
||||
{
|
||||
// Deallocate players
|
||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ void Environment::removePlayer(u16 peer_id)
|
|||
{
|
||||
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();)
|
||||
{
|
||||
Player *player = *i;
|
||||
|
@ -103,7 +104,7 @@ void Environment::removePlayer(u16 peer_id)
|
|||
|
||||
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) {
|
||||
if (strcmp((*it)->getName(), name) == 0) {
|
||||
delete *it;
|
||||
|
@ -115,8 +116,9 @@ void Environment::removePlayer(const char *name)
|
|||
|
||||
Player * Environment::getPlayer(u16 peer_id)
|
||||
{
|
||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
if(player->peer_id == peer_id)
|
||||
return player;
|
||||
|
@ -126,8 +128,9 @@ Player * Environment::getPlayer(u16 peer_id)
|
|||
|
||||
Player * Environment::getPlayer(const char *name)
|
||||
{
|
||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
if(strcmp(player->getName(), name) == 0)
|
||||
return player;
|
||||
|
@ -137,13 +140,15 @@ Player * Environment::getPlayer(const char *name)
|
|||
|
||||
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 j = 0;
|
||||
for(std::vector<Player*>::iterator
|
||||
for(std::list<Player*>::iterator
|
||||
i = connected_players.begin();
|
||||
i != connected_players.end(); ++i) {
|
||||
if(j == chosen_one) {
|
||||
i != connected_players.end(); ++i)
|
||||
{
|
||||
if(j == chosen_one)
|
||||
{
|
||||
Player *player = *i;
|
||||
return player;
|
||||
}
|
||||
|
@ -154,15 +159,17 @@ Player * Environment::getRandomConnectedPlayer()
|
|||
|
||||
Player * Environment::getNearestConnectedPlayer(v3f pos)
|
||||
{
|
||||
std::vector<Player*> connected_players = getPlayers(true);
|
||||
std::list<Player*> connected_players = getPlayers(true);
|
||||
f32 nearest_d = 0;
|
||||
Player *nearest_player = NULL;
|
||||
for(std::vector<Player*>::iterator
|
||||
for(std::list<Player*>::iterator
|
||||
i = connected_players.begin();
|
||||
i != connected_players.end(); ++i) {
|
||||
i != connected_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
f32 d = player->getPosition().getDistanceFrom(pos);
|
||||
if(d < nearest_d || nearest_player == NULL) {
|
||||
if(d < nearest_d || nearest_player == NULL)
|
||||
{
|
||||
nearest_d = d;
|
||||
nearest_player = player;
|
||||
}
|
||||
|
@ -170,20 +177,22 @@ Player * Environment::getNearestConnectedPlayer(v3f pos)
|
|||
return nearest_player;
|
||||
}
|
||||
|
||||
std::vector<Player*> Environment::getPlayers()
|
||||
std::list<Player*> Environment::getPlayers()
|
||||
{
|
||||
return m_players;
|
||||
}
|
||||
|
||||
std::vector<Player*> Environment::getPlayers(bool ignore_disconnected)
|
||||
std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
|
||||
{
|
||||
std::vector<Player*> newlist;
|
||||
for(std::vector<Player*>::iterator
|
||||
std::list<Player*> newlist;
|
||||
for(std::list<Player*>::iterator
|
||||
i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
|
||||
if(ignore_disconnected) {
|
||||
if(ignore_disconnected)
|
||||
{
|
||||
// Ignore disconnected players
|
||||
if(player->peer_id == 0)
|
||||
continue;
|
||||
|
@ -203,42 +212,24 @@ u32 Environment::getDayNightRatio()
|
|||
|
||||
void Environment::setTimeOfDaySpeed(float speed)
|
||||
{
|
||||
JMutexAutoLock(this->m_timeofday_lock);
|
||||
JMutexAutoLock(this->m_lock);
|
||||
m_time_of_day_speed = speed;
|
||||
}
|
||||
|
||||
float Environment::getTimeOfDaySpeed()
|
||||
{
|
||||
JMutexAutoLock(this->m_timeofday_lock);
|
||||
JMutexAutoLock(this->m_lock);
|
||||
float retval = m_time_of_day_speed;
|
||||
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)
|
||||
{
|
||||
// getTimeOfDaySpeed lock the value we need to prevent MT problems
|
||||
float day_speed = getTimeOfDaySpeed();
|
||||
float day_speed = 0;
|
||||
{
|
||||
JMutexAutoLock(this->m_lock);
|
||||
day_speed = m_time_of_day_speed;
|
||||
}
|
||||
|
||||
m_time_counter += dtime;
|
||||
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,
|
||||
std::set<v3s16> &blocks_removed,
|
||||
std::set<v3s16> &blocks_added)
|
||||
|
@ -305,7 +296,7 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions,
|
|||
Create the new 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)
|
||||
{
|
||||
fillRadiusBlock(*i, radius, newlist);
|
||||
|
@ -382,7 +373,7 @@ ServerEnvironment::~ServerEnvironment()
|
|||
m_map->drop();
|
||||
|
||||
// Delete ActiveBlockModifiers
|
||||
for(std::vector<ABMWithState>::iterator
|
||||
for(std::list<ABMWithState>::iterator
|
||||
i = m_abms.begin(); i != m_abms.end(); ++i){
|
||||
delete i->abm;
|
||||
}
|
||||
|
@ -404,8 +395,8 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
|
|||
|
||||
//calculate normalized direction vector
|
||||
v3f normalized_vector = v3f((pos2.X - pos1.X)/distance,
|
||||
(pos2.Y - pos1.Y)/distance,
|
||||
(pos2.Z - pos1.Z)/distance);
|
||||
(pos2.Y - pos1.Y)/distance,
|
||||
(pos2.Z - pos1.Z)/distance);
|
||||
|
||||
//find out if there's a node on path between pos1 and pos2
|
||||
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";
|
||||
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) {
|
||||
RemotePlayer *player = static_cast<RemotePlayer*>(*it);
|
||||
|
@ -558,9 +549,9 @@ class ABMHandler
|
|||
{
|
||||
private:
|
||||
ServerEnvironment *m_env;
|
||||
std::map<content_t, std::vector<ActiveABM> > m_aabms;
|
||||
std::map<content_t, std::list<ActiveABM> > m_aabms;
|
||||
public:
|
||||
ABMHandler(std::vector<ABMWithState> &abms,
|
||||
ABMHandler(std::list<ABMWithState> &abms,
|
||||
float dtime_s, ServerEnvironment *env,
|
||||
bool use_timers):
|
||||
m_env(env)
|
||||
|
@ -568,8 +559,8 @@ public:
|
|||
if(dtime_s < 0.001)
|
||||
return;
|
||||
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||
for(std::vector<ABMWithState>::iterator
|
||||
i = abms.begin(); i != abms.end(); ++i) {
|
||||
for(std::list<ABMWithState>::iterator
|
||||
i = abms.begin(); i != abms.end(); ++i){
|
||||
ActiveBlockModifier *abm = i->abm;
|
||||
float trigger_interval = abm->getTriggerInterval();
|
||||
if(trigger_interval < 0.001)
|
||||
|
@ -613,10 +604,10 @@ public:
|
|||
k != ids.end(); 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);
|
||||
if(j == m_aabms.end()){
|
||||
std::vector<ActiveABM> aabmlist;
|
||||
std::list<ActiveABM> aabmlist;
|
||||
m_aabms[c] = aabmlist;
|
||||
j = m_aabms.find(c);
|
||||
}
|
||||
|
@ -673,13 +664,14 @@ public:
|
|||
content_t c = n.getContent();
|
||||
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);
|
||||
if(j == m_aabms.end())
|
||||
continue;
|
||||
|
||||
for(std::vector<ActiveABM>::iterator
|
||||
i = j->second.begin(); i != j->second.end(); i++) {
|
||||
for(std::list<ActiveABM>::iterator
|
||||
i = j->second.begin(); i != j->second.end(); i++)
|
||||
{
|
||||
if(myrand() % i->chance != 0)
|
||||
continue;
|
||||
|
||||
|
@ -859,10 +851,11 @@ void ServerEnvironment::clearAllObjects()
|
|||
{
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Removing all active objects"<<std::endl;
|
||||
std::vector<u16> objects_to_remove;
|
||||
std::list<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
i != m_active_objects.end(); ++i)
|
||||
{
|
||||
ServerActiveObject* obj = i->second;
|
||||
if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||
continue;
|
||||
|
@ -895,15 +888,15 @@ void ServerEnvironment::clearAllObjects()
|
|||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
|
||||
// Remove references from m_active_objects
|
||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i) {
|
||||
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i)
|
||||
{
|
||||
m_active_objects.erase(*i);
|
||||
}
|
||||
|
||||
// Get list of loaded blocks
|
||||
std::vector<v3s16> loaded_blocks;
|
||||
std::list<v3s16> loaded_blocks;
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Listing all loaded blocks"<<std::endl;
|
||||
m_map->listAllLoadedBlocks(loaded_blocks);
|
||||
|
@ -912,7 +905,7 @@ void ServerEnvironment::clearAllObjects()
|
|||
<<loaded_blocks.size()<<std::endl;
|
||||
|
||||
// Get list of loadable blocks
|
||||
std::vector<v3s16> loadable_blocks;
|
||||
std::list<v3s16> loadable_blocks;
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Listing all loadable blocks"<<std::endl;
|
||||
m_map->listAllLoadableBlocks(loadable_blocks);
|
||||
|
@ -922,8 +915,9 @@ void ServerEnvironment::clearAllObjects()
|
|||
<<", now clearing"<<std::endl;
|
||||
|
||||
// Grab a reference on each loaded block to avoid unloading it
|
||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i) {
|
||||
for(std::list<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i)
|
||||
{
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
assert(block);
|
||||
|
@ -937,8 +931,9 @@ void ServerEnvironment::clearAllObjects()
|
|||
u32 num_blocks_checked = 0;
|
||||
u32 num_blocks_cleared = 0;
|
||||
u32 num_objs_cleared = 0;
|
||||
for(std::vector<v3s16>::iterator i = loadable_blocks.begin();
|
||||
i != loadable_blocks.end(); ++i) {
|
||||
for(std::list<v3s16>::iterator i = loadable_blocks.begin();
|
||||
i != loadable_blocks.end(); ++i)
|
||||
{
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->emergeBlock(p, false);
|
||||
if(!block){
|
||||
|
@ -974,8 +969,9 @@ void ServerEnvironment::clearAllObjects()
|
|||
m_map->unloadUnreferencedBlocks();
|
||||
|
||||
// Drop references that were added above
|
||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i) {
|
||||
for(std::list<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i)
|
||||
{
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
assert(block);
|
||||
|
@ -1016,7 +1012,7 @@ void ServerEnvironment::step(float dtime)
|
|||
*/
|
||||
{
|
||||
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)
|
||||
{
|
||||
Player *player = *i;
|
||||
|
@ -1039,15 +1035,15 @@ void ServerEnvironment::step(float dtime)
|
|||
/*
|
||||
Get player block positions
|
||||
*/
|
||||
std::vector<v3s16> players_blockpos;
|
||||
for(std::vector<Player*>::iterator
|
||||
std::list<v3s16> players_blockpos;
|
||||
for(std::list<Player*>::iterator
|
||||
i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
// Ignore disconnected players
|
||||
if(player->peer_id == 0)
|
||||
continue;
|
||||
|
||||
v3s16 blockpos = getNodeBlockPos(
|
||||
floatToInt(player->getPosition(), BS));
|
||||
players_blockpos.push_back(blockpos);
|
||||
|
@ -1182,7 +1178,7 @@ void ServerEnvironment::step(float dtime)
|
|||
<<") being handled"<<std::endl;*/
|
||||
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
if(block == NULL)
|
||||
if(block==NULL)
|
||||
continue;
|
||||
|
||||
// Set current time as timestamp
|
||||
|
@ -1239,8 +1235,7 @@ void ServerEnvironment::step(float dtime)
|
|||
while(!obj->m_messages_out.empty())
|
||||
{
|
||||
m_active_object_messages.push_back(
|
||||
obj->m_messages_out.front());
|
||||
obj->m_messages_out.pop();
|
||||
obj->m_messages_out.pop_front());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1547,10 +1542,11 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
|||
*/
|
||||
void ServerEnvironment::removeRemovedObjects()
|
||||
{
|
||||
std::vector<u16> objects_to_remove;
|
||||
std::list<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
i != m_active_objects.end(); ++i)
|
||||
{
|
||||
u16 id = i->first;
|
||||
ServerActiveObject* obj = i->second;
|
||||
// This shouldn't happen but check it
|
||||
|
@ -1620,13 +1616,13 @@ void ServerEnvironment::removeRemovedObjects()
|
|||
// Delete
|
||||
if(obj->environmentDeletes())
|
||||
delete obj;
|
||||
|
||||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
// Remove references from m_active_objects
|
||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i) {
|
||||
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++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)
|
||||
{
|
||||
if(block == NULL)
|
||||
if(block==NULL)
|
||||
return;
|
||||
|
||||
// Ignore if no stored objects (to not set changed flag)
|
||||
if(block->m_static_objects.m_stored.empty())
|
||||
return;
|
||||
|
||||
verbosestream<<"ServerEnvironment::activateObjects(): "
|
||||
<<"activating objects of block "<<PP(block->getPos())
|
||||
<<" ("<<block->m_static_objects.m_stored.size()
|
||||
<<" objects)"<<std::endl;
|
||||
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: "
|
||||
<<block->m_static_objects.m_stored.size()<<" in "
|
||||
<<PP(block->getPos())
|
||||
|
@ -1696,17 +1690,20 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
|||
}
|
||||
|
||||
// Activate stored objects
|
||||
std::vector<StaticObject> new_stored;
|
||||
for (std::vector<StaticObject>::iterator
|
||||
std::list<StaticObject> new_stored;
|
||||
for(std::list<StaticObject>::iterator
|
||||
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;
|
||||
|
||||
// Create an active object from the data
|
||||
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(obj == NULL) {
|
||||
if(obj==NULL)
|
||||
{
|
||||
errorstream<<"ServerEnvironment::activateObjects(): "
|
||||
<<"failed to create active object from static object "
|
||||
<<"in block "<<PP(s_obj.pos/BS)
|
||||
|
@ -1725,9 +1722,10 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
|||
// Clear stored list
|
||||
block->m_static_objects.m_stored.clear();
|
||||
// Add leftover failed stuff to stored list
|
||||
for(std::vector<StaticObject>::iterator
|
||||
for(std::list<StaticObject>::iterator
|
||||
i = new_stored.begin();
|
||||
i != new_stored.end(); ++i) {
|
||||
i != new_stored.end(); ++i)
|
||||
{
|
||||
StaticObject &s_obj = *i;
|
||||
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)
|
||||
{
|
||||
std::vector<u16> objects_to_remove;
|
||||
std::list<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
i != m_active_objects.end(); ++i)
|
||||
{
|
||||
ServerActiveObject* obj = i->second;
|
||||
assert(obj);
|
||||
|
||||
|
@ -1987,8 +1986,9 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|||
}
|
||||
|
||||
// Remove references from m_active_objects
|
||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i) {
|
||||
for(std::list<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i)
|
||||
{
|
||||
m_active_objects.erase(*i);
|
||||
}
|
||||
}
|
||||
|
@ -2025,8 +2025,9 @@ ClientEnvironment::~ClientEnvironment()
|
|||
delete i->second;
|
||||
}
|
||||
|
||||
for(std::vector<ClientSimpleObject*>::iterator
|
||||
i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i) {
|
||||
for(std::list<ClientSimpleObject*>::iterator
|
||||
i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
|
||||
|
@ -2058,8 +2059,9 @@ void ClientEnvironment::addPlayer(Player *player)
|
|||
|
||||
LocalPlayer * ClientEnvironment::getLocalPlayer()
|
||||
{
|
||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
if(player->isLocal())
|
||||
return (LocalPlayer*)player;
|
||||
|
@ -2082,7 +2084,7 @@ void ClientEnvironment::step(float dtime)
|
|||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
// collision info queue
|
||||
std::vector<CollisionInfo> player_collisions;
|
||||
std::list<CollisionInfo> player_collisions;
|
||||
|
||||
/*
|
||||
Get the speed the player is going
|
||||
|
@ -2197,8 +2199,10 @@ void ClientEnvironment::step(float dtime)
|
|||
|
||||
//std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
|
||||
|
||||
for(std::vector<CollisionInfo>::iterator i = player_collisions.begin();
|
||||
i != player_collisions.end(); ++i) {
|
||||
for(std::list<CollisionInfo>::iterator
|
||||
i = player_collisions.begin();
|
||||
i != player_collisions.end(); ++i)
|
||||
{
|
||||
CollisionInfo &info = *i;
|
||||
v3f speed_diff = info.new_speed - info.old_speed;;
|
||||
// Handle only fall damage
|
||||
|
@ -2313,14 +2317,16 @@ void ClientEnvironment::step(float dtime)
|
|||
/*
|
||||
Stuff that can be done in an arbitarily large dtime
|
||||
*/
|
||||
for(std::vector<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i) {
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); ++i)
|
||||
{
|
||||
Player *player = *i;
|
||||
|
||||
/*
|
||||
Handle non-local players
|
||||
*/
|
||||
if(player->isLocal() == false) {
|
||||
if(player->isLocal() == false)
|
||||
{
|
||||
// Move
|
||||
player->move(dtime, this, 100*BS);
|
||||
|
||||
|
@ -2381,18 +2387,16 @@ void ClientEnvironment::step(float dtime)
|
|||
Step and handle simple objects
|
||||
*/
|
||||
g_profiler->avg("CEnv: num of simple objects", m_simple_objects.size());
|
||||
for(std::vector<ClientSimpleObject*>::iterator
|
||||
i = m_simple_objects.begin(); i != m_simple_objects.end();) {
|
||||
std::vector<ClientSimpleObject*>::iterator cur = i;
|
||||
ClientSimpleObject *simple = *cur;
|
||||
|
||||
for(std::list<ClientSimpleObject*>::iterator
|
||||
i = m_simple_objects.begin(); i != m_simple_objects.end();)
|
||||
{
|
||||
ClientSimpleObject *simple = *i;
|
||||
std::list<ClientSimpleObject*>::iterator cur = i;
|
||||
++i;
|
||||
simple->step(dtime);
|
||||
if(simple->m_to_be_removed) {
|
||||
if(simple->m_to_be_removed){
|
||||
delete simple;
|
||||
i = m_simple_objects.erase(cur);
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
m_simple_objects.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2484,7 +2488,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
|||
const std::string &init_data)
|
||||
{
|
||||
ClientActiveObject* obj =
|
||||
ClientActiveObject::create((ActiveObjectType) type, m_gamedef, this);
|
||||
ClientActiveObject::create(type, m_gamedef, this);
|
||||
if(obj == NULL)
|
||||
{
|
||||
infostream<<"ClientEnvironment::addActiveObject(): "
|
||||
|
|
|
@ -75,19 +75,28 @@ public:
|
|||
Player * getPlayer(const char *name);
|
||||
Player * getRandomConnectedPlayer();
|
||||
Player * getNearestConnectedPlayer(v3f pos);
|
||||
std::vector<Player*> getPlayers();
|
||||
std::vector<Player*> getPlayers(bool ignore_disconnected);
|
||||
std::list<Player*> getPlayers();
|
||||
std::list<Player*> getPlayers(bool ignore_disconnected);
|
||||
|
||||
u32 getDayNightRatio();
|
||||
|
||||
// 0-23999
|
||||
virtual void setTimeOfDay(u32 time);
|
||||
u32 getTimeOfDay();
|
||||
float getTimeOfDayF();
|
||||
virtual void setTimeOfDay(u32 time)
|
||||
{
|
||||
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 setTimeOfDaySpeed(float speed);
|
||||
|
||||
float getTimeOfDaySpeed();
|
||||
|
||||
void setDayNightRatioOverride(bool enable, u32 value)
|
||||
|
@ -101,7 +110,7 @@ public:
|
|||
|
||||
protected:
|
||||
// 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
|
||||
u32 m_time_of_day;
|
||||
// Time of day in 0...1
|
||||
|
@ -125,8 +134,7 @@ protected:
|
|||
bool m_cache_enable_shaders;
|
||||
|
||||
private:
|
||||
JMutex m_timeofday_lock;
|
||||
JMutex m_time_lock;
|
||||
JMutex m_lock;
|
||||
|
||||
};
|
||||
|
||||
|
@ -174,7 +182,7 @@ struct ABMWithState
|
|||
class ActiveBlockList
|
||||
{
|
||||
public:
|
||||
void update(std::vector<v3s16> &active_positions,
|
||||
void update(std::list<v3s16> &active_positions,
|
||||
s16 radius,
|
||||
std::set<v3s16> &blocks_removed,
|
||||
std::set<v3s16> &blocks_added);
|
||||
|
@ -393,7 +401,7 @@ private:
|
|||
u32 m_game_time;
|
||||
// A helper variable for incrementing the latter
|
||||
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
|
||||
float m_recommended_send_interval;
|
||||
// Estimate for general maximum lag as determined by server.
|
||||
|
@ -521,7 +529,7 @@ private:
|
|||
IGameDef *m_gamedef;
|
||||
IrrlichtDevice *m_irr;
|
||||
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;
|
||||
IntervalLimiter m_active_object_light_update_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 "network/networkprotocol.h"
|
||||
#include "clientserver.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
#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 "main.h" // For g_settings
|
||||
#include "itemdef.h"
|
||||
#include "client/tile.h" // For TextureSource
|
||||
#include "tile.h" // For TextureSource
|
||||
#include "shader.h" // For ShaderSource
|
||||
#include "logoutputbuffer.h"
|
||||
#include "subgame.h"
|
||||
|
@ -492,7 +492,7 @@ private:
|
|||
color(color)
|
||||
{}
|
||||
};
|
||||
std::vector<Piece> m_log;
|
||||
std::list<Piece> m_log;
|
||||
public:
|
||||
u32 m_log_max_size;
|
||||
|
||||
|
@ -515,7 +515,7 @@ public:
|
|||
{
|
||||
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++) {
|
||||
const Piece &piece = *k;
|
||||
|
||||
|
@ -613,7 +613,7 @@ public:
|
|||
float lastscaledvalue = 0.0;
|
||||
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++) {
|
||||
const Piece &piece = *j;
|
||||
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]"
|
||||
#else
|
||||
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
||||
#endif
|
||||
|
||||
static void show_chat_menu(GUIFormSpecMenu **cur_formspec,
|
||||
InventoryManager *invmgr, IGameDef *gamedef,
|
||||
|
@ -1078,7 +1074,7 @@ static void show_deathscreen(GUIFormSpecMenu **cur_formspec,
|
|||
std::string(FORMSPEC_VERSION_STRING) +
|
||||
SIZE_TAG
|
||||
"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") + "]"
|
||||
;
|
||||
|
||||
|
@ -1137,7 +1133,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
|
|||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
||||
<< wide_to_narrow(wstrgettext("Change Password")) << "]";
|
||||
}
|
||||
|
||||
|
||||
#ifndef __ANDROID__
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
|
||||
<< 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");
|
||||
|
||||
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL);
|
||||
(*cur_formspec)->setFocus(L"btn_continue");
|
||||
|
||||
(*cur_formspec)->doPause = true;
|
||||
}
|
||||
|
||||
|
@ -1253,7 +1249,6 @@ struct KeyCache {
|
|||
KEYMAP_ID_FREEMOVE,
|
||||
KEYMAP_ID_FASTMOVE,
|
||||
KEYMAP_ID_NOCLIP,
|
||||
KEYMAP_ID_CINEMATIC,
|
||||
KEYMAP_ID_SCREENSHOT,
|
||||
KEYMAP_ID_TOGGLE_HUD,
|
||||
KEYMAP_ID_TOGGLE_CHAT,
|
||||
|
@ -1302,7 +1297,6 @@ void KeyCache::populate()
|
|||
key[KEYMAP_ID_FREEMOVE] = getKeySetting("keymap_freemove");
|
||||
key[KEYMAP_ID_FASTMOVE] = getKeySetting("keymap_fastmove");
|
||||
key[KEYMAP_ID_NOCLIP] = getKeySetting("keymap_noclip");
|
||||
key[KEYMAP_ID_CINEMATIC] = getKeySetting("keymap_cinematic");
|
||||
key[KEYMAP_ID_SCREENSHOT] = getKeySetting("keymap_screenshot");
|
||||
key[KEYMAP_ID_TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
|
||||
key[KEYMAP_ID_TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
|
||||
|
@ -1499,7 +1493,6 @@ protected:
|
|||
void toggleFreeMoveAlt(float *statustext_time, float *jump_timer);
|
||||
void toggleFast(float *statustext_time);
|
||||
void toggleNoClip(float *statustext_time);
|
||||
void toggleCinematic(float *statustext_time);
|
||||
|
||||
void toggleChat(float *statustext_time, bool *flag);
|
||||
void toggleHud(float *statustext_time, bool *flag);
|
||||
|
@ -1740,7 +1733,6 @@ void Game::run()
|
|||
{
|
||||
ProfilerGraph graph;
|
||||
RunStats stats = { 0 };
|
||||
CameraOrientation cam_view_target = { 0 };
|
||||
CameraOrientation cam_view = { 0 };
|
||||
GameRunData runData = { 0 };
|
||||
FpsControl draw_times = { 0 };
|
||||
|
@ -1796,17 +1788,7 @@ void Game::run()
|
|||
updateProfilers(runData, stats, draw_times, dtime);
|
||||
processUserInput(&flags, &runData, dtime);
|
||||
// Update camera before player movement to avoid camera lag of one frame
|
||||
updateCameraDirection(&cam_view_target, &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;
|
||||
updateCameraDirection(&cam_view, &flags);
|
||||
updatePlayerControl(cam_view);
|
||||
step(&dtime);
|
||||
processClientEvents(&cam_view, &runData.damage_flash);
|
||||
|
@ -2582,8 +2564,6 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
|
|||
toggleFast(statustext_time);
|
||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_NOCLIP])) {
|
||||
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])) {
|
||||
client->makeScreenshot(device);
|
||||
} else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
|
||||
|
@ -2689,15 +2669,6 @@ void Game::dropSelectedItem()
|
|||
|
||||
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;
|
||||
|
||||
PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client);
|
||||
|
@ -2770,16 +2741,6 @@ void Game::toggleNoClip(float *statustext_time)
|
|||
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)
|
||||
{
|
||||
|
@ -3257,13 +3218,10 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time,
|
|||
v3s16 old_camera_offset = camera->getOffset();
|
||||
|
||||
if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
|
||||
camera->toggleCameraMode();
|
||||
GenericCAO *playercao = player->getCAO();
|
||||
|
||||
// If playercao not loaded, don't change camera
|
||||
if (playercao == NULL)
|
||||
return;
|
||||
|
||||
camera->toggleCameraMode();
|
||||
assert(playercao != NULL);
|
||||
|
||||
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,
|
||||
const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
|
||||
const CameraOrientation &cam)
|
||||
|
@ -4045,7 +3981,6 @@ void Game::updateGui(float *statustext_time, const RunStats &stats,
|
|||
<< ", " << (player_position.Y / BS)
|
||||
<< ", " << (player_position.Z / BS)
|
||||
<< ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw))
|
||||
<< " " << yawToDirectionString(cam.camera_yaw)
|
||||
<< ") (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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,24 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "log.h"
|
||||
|
||||
#if USE_GETTEXT && defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
#include <WinNls.h>
|
||||
#include <map>
|
||||
#include <direct.h>
|
||||
#include "filesys.h"
|
||||
|
||||
#define setlocale(category, localename) \
|
||||
setlocale(category, MSVC_LocaleLookup(localename))
|
||||
#define setlocale(category,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)
|
||||
{
|
||||
char* endptr = 0;
|
||||
int LOCALEID = strtol(pStr, &endptr,16);
|
||||
int LOCALEID = strtol(pStr,&endptr,16);
|
||||
|
||||
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
if (GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SISO639LANGNAME,
|
||||
|
@ -52,7 +52,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
|||
|
||||
std::wstring name = buffer;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SISO3166CTRYNAME,
|
||||
|
@ -61,7 +61,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
|||
|
||||
std::wstring country = buffer;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SENGLISHLANGUAGENAME,
|
||||
|
@ -96,7 +96,7 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
|
|||
}
|
||||
|
||||
if (first_use) {
|
||||
EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
||||
EnumSystemLocalesA(UpdateLocaleCallback,LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
||||
first_use = false;
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
|||
if (current_language_var != configured_language) {
|
||||
STARTUPINFO startupinfo;
|
||||
PROCESS_INFORMATION processinfo;
|
||||
memset(&startupinfo, 0, sizeof(startupinfo));
|
||||
memset(&processinfo, 0, sizeof(processinfo));
|
||||
memset(&startupinfo,0,sizeof(startupinfo));
|
||||
memset(&processinfo,0,sizeof(processinfo));
|
||||
errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
|
||||
|
||||
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 **/
|
||||
std::string appname = argv[0];
|
||||
if (appname.substr(appname.length() - 4) != ".exe") {
|
||||
if (appname.substr(appname.length() -4) != ".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" */
|
||||
/* to ensure formspec parameters are evaluated correct! */
|
||||
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
setlocale(LC_NUMERIC,"C");
|
||||
infostream << "Message locale is now set to: "
|
||||
<< 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 std::wstring narrow_to_wide(const std::string &mbs);
|
||||
|
||||
|
||||
// You must free the returned string!
|
||||
inline const wchar_t *wgettext(const char *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)
|
||||
{
|
||||
const wchar_t *tmp = wgettext(text.c_str());
|
||||
std::wstring retval = (std::wstring)tmp;
|
||||
delete[] tmp;
|
||||
return retval;
|
||||
return narrow_to_wide(gettext(text.c_str()));
|
||||
}
|
||||
|
||||
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 "main.h" // for g_settings
|
||||
#include "porting.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "fontengine.h"
|
||||
#include "log.h"
|
||||
#include "gettext.h"
|
||||
|
@ -99,7 +99,7 @@ GUIChatConsole::GUIChatConsole(
|
|||
{
|
||||
core::dimension2d<u32> dim = m_font->getDimension(L"M");
|
||||
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.Y = MYMAX(m_fontsize.Y, 1);
|
||||
|
@ -109,10 +109,7 @@ GUIChatConsole::GUIChatConsole(
|
|||
}
|
||||
|
||||
GUIChatConsole::~GUIChatConsole()
|
||||
{
|
||||
if (m_font)
|
||||
m_font->drop();
|
||||
}
|
||||
{}
|
||||
|
||||
void GUIChatConsole::openConsole(f32 height)
|
||||
{
|
||||
|
|
|
@ -122,6 +122,9 @@ private:
|
|||
// font
|
||||
gui::IGUIFont* m_font;
|
||||
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"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include <GLES/gl.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "modalMenu.h"
|
||||
#include "guiFormSpecMenu.h"
|
||||
#include "sound.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Typedefs and macros */
|
||||
|
|
|
@ -37,8 +37,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <IGUITabControl.h>
|
||||
#include <IGUIComboBox.h>
|
||||
#include "log.h"
|
||||
#include "client/tile.h" // ITextureSource
|
||||
#include "tile.h" // ITextureSource
|
||||
#include "hud.h" // drawItemStack
|
||||
#include "hex.h"
|
||||
#include "util/string.h"
|
||||
#include "util/numeric.h"
|
||||
#include "filesys.h"
|
||||
#include "gettime.h"
|
||||
#include "gettext.h"
|
||||
|
@ -47,10 +50,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "client.h"
|
||||
#include "fontengine.h"
|
||||
#include "util/hex.h"
|
||||
#include "util/numeric.h"
|
||||
#include "util/string.h" // for parseColorString()
|
||||
#include "fontengine.h"
|
||||
|
||||
#define MY_CHECKPOS(a,b) \
|
||||
if (v_pos.size() != 2) { \
|
||||
|
@ -96,7 +97,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
|||
m_form_src(fsrc),
|
||||
m_text_dst(tdst),
|
||||
m_formspec_version(0),
|
||||
m_focused_element(L""),
|
||||
m_font(NULL)
|
||||
#ifdef __ANDROID__
|
||||
,m_JavaDialogFieldName(L"")
|
||||
|
@ -1757,6 +1757,8 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
|||
<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
/* useless to regenerate without a screensize */
|
||||
|
@ -1773,10 +1775,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||
mydata.table_dyndata[tablename] = table->getDynamicData();
|
||||
}
|
||||
|
||||
//set focus
|
||||
if (!m_focused_element.empty())
|
||||
mydata.focused_fieldname = m_focused_element;
|
||||
|
||||
//preserve focus
|
||||
gui::IGUIElement *focused_element = Environment->getFocus();
|
||||
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 "modalMenu.h"
|
||||
#include "guiTable.h"
|
||||
#include "network/networkprotocol.h"
|
||||
#include "clientserver.h"
|
||||
|
||||
class IGameDef;
|
||||
class InventoryManager;
|
||||
|
@ -246,20 +246,13 @@ public:
|
|||
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_lockscreensize = basescreensize;
|
||||
}
|
||||
|
||||
void removeChildren();
|
||||
void setInitialFocus();
|
||||
|
||||
void setFocus(std::wstring elementname)
|
||||
{
|
||||
m_focused_element = elementname;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove and re-add (or reposition) stuff
|
||||
*/
|
||||
|
@ -355,7 +348,6 @@ private:
|
|||
IFormSource *m_form_src;
|
||||
TextDest *m_text_dst;
|
||||
unsigned int m_formspec_version;
|
||||
std::wstring m_focused_element;
|
||||
|
||||
typedef struct {
|
||||
bool explicit_size;
|
||||
|
|
|
@ -51,7 +51,6 @@ enum
|
|||
GUI_ID_KEY_FAST_BUTTON,
|
||||
GUI_ID_KEY_JUMP_BUTTON,
|
||||
GUI_ID_KEY_NOCLIP_BUTTON,
|
||||
GUI_ID_KEY_CINEMATIC_BUTTON,
|
||||
GUI_ID_KEY_CHAT_BUTTON,
|
||||
GUI_ID_KEY_CMD_BUTTON,
|
||||
GUI_ID_KEY_CONSOLE_BUTTON,
|
||||
|
@ -138,27 +137,27 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
|||
{
|
||||
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);
|
||||
Environment->addStaticText(k->button_name, rect, false, true, this, -1);
|
||||
}
|
||||
|
||||
{
|
||||
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());
|
||||
k->button = Environment->addButton(rect, this, k->id, text);
|
||||
delete[] text;
|
||||
}
|
||||
if(i + 1 == KMaxButtonPerColumns)
|
||||
offset = v2s32(260, 60);
|
||||
offset = v2s32(250, 60);
|
||||
else
|
||||
offset += v2s32(0, 25);
|
||||
}
|
||||
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y + 5;
|
||||
s32 option_x = offset.X + 10;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 180;
|
||||
{
|
||||
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_y = offset.Y + 5;
|
||||
u32 option_w = 280;
|
||||
s32 option_x = offset.X + 10;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 220;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
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()
|
||||
{
|
||||
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_LEFT_BUTTON, wgettext("Left"), "keymap_left");
|
||||
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_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
|
||||
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_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
|
||||
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_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_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_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_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
|
||||
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_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
|
||||
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_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
|
||||
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_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
|
||||
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_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_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_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");
|
||||
}
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
|||
*/
|
||||
s32 ypos = 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
text = wgettext("Old Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
|
@ -119,8 +119,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
|||
}
|
||||
ypos += 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
text = wgettext("New Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
|
@ -134,8 +134,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
|||
}
|
||||
ypos += 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
text = wgettext("Confirm Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <IGUIScrollBar.h>
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "gettime.h"
|
||||
#include "util/string.h"
|
||||
#include "util/numeric.h"
|
||||
|
|
|
@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "settings.h"
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ static void httpfetch_deliver_result(const HTTPFetchResult &fetch_result)
|
|||
unsigned long caller = fetch_result.caller;
|
||||
if (caller != HTTPFETCH_DISCARD) {
|
||||
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
|
||||
const unsigned long discard = HTTPFETCH_DISCARD;
|
||||
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);
|
||||
if (it == g_httpfetch_results.end()) {
|
||||
verbosestream << "httpfetch_caller_alloc: allocating "
|
||||
<< caller << std::endl;
|
||||
verbosestream<<"httpfetch_caller_alloc: allocating "
|
||||
<<caller<<std::endl;
|
||||
// Access element to create it
|
||||
g_httpfetch_results[caller];
|
||||
return caller;
|
||||
|
@ -102,19 +102,19 @@ bool httpfetch_async_get(unsigned long caller, HTTPFetchResult &fetch_result)
|
|||
JMutexAutoLock lock(g_httpfetch_mutex);
|
||||
|
||||
// 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);
|
||||
if (it == g_httpfetch_results.end())
|
||||
return false;
|
||||
|
||||
// Check that result queue is nonempty
|
||||
std::queue<HTTPFetchResult> &caller_results = it->second;
|
||||
std::list<HTTPFetchResult> &caller_results = it->second;
|
||||
if (caller_results.empty())
|
||||
return false;
|
||||
|
||||
// Pop first result
|
||||
fetch_result = caller_results.front();
|
||||
caller_results.pop();
|
||||
caller_results.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,7 @@ private:
|
|||
HTTPFetchRequest request;
|
||||
HTTPFetchResult result;
|
||||
std::ostringstream oss;
|
||||
char *post_fields;
|
||||
struct curl_slist *http_header;
|
||||
curl_httppost *post;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "gamedef.h"
|
||||
#include "itemdef.h"
|
||||
#include "inventory.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#include "localplayer.h"
|
||||
#include "camera.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 "mesh.h"
|
||||
#include "wieldmesh.h"
|
||||
#include "client/tile.h"
|
||||
#include "tile.h"
|
||||
#endif
|
||||
#include "log.h"
|
||||
#include "main.h" // g_settings
|
||||
|
@ -249,8 +249,8 @@ public:
|
|||
virtual ~CItemDefManager()
|
||||
{
|
||||
#ifndef SERVER
|
||||
const std::vector<ClientCached*> &values = m_clientcached.getValues();
|
||||
for(std::vector<ClientCached*>::const_iterator
|
||||
const std::list<ClientCached*> &values = m_clientcached.getValues();
|
||||
for(std::list<ClientCached*>::const_iterator
|
||||
i = values.begin(); i != values.end(); ++i)
|
||||
{
|
||||
ClientCached *cc = *i;
|
||||
|
@ -362,6 +362,8 @@ public:
|
|||
|
||||
scene::IMesh *node_mesh = NULL;
|
||||
|
||||
bool reenable_shaders = false;
|
||||
|
||||
if (need_rtt_mesh || need_wield_mesh) {
|
||||
u8 param1 = 0;
|
||||
if (f.param_type == CPT_LIGHT)
|
||||
|
@ -370,7 +372,11 @@ public:
|
|||
/*
|
||||
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;
|
||||
if (f.param_type_2 == CPT2_WALLMOUNTED)
|
||||
param2 = 1;
|
||||
|
@ -437,6 +443,9 @@ public:
|
|||
|
||||
if (node_mesh)
|
||||
node_mesh->drop();
|
||||
|
||||
if (reenable_shaders)
|
||||
g_settings->setBool("enable_shaders",true);
|
||||
}
|
||||
|
||||
// Put in cache
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#elif __MACH__
|
||||
#include <mach/mach.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/semaphore.h>
|
||||
|
@ -43,7 +43,7 @@
|
|||
class Event {
|
||||
#ifdef _WIN32
|
||||
HANDLE hEvent;
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#elif __MACH__
|
||||
semaphore_t sem;
|
||||
#else
|
||||
sem_t sem;
|
||||
|
|
|
@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#define MAX_SEMAPHORE_COUNT 1024
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#elif __MACH__
|
||||
#include <pthread.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/task.h>
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
private:
|
||||
#if defined(WIN32)
|
||||
HANDLE m_hSemaphore;
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#elif __MACH__
|
||||
semaphore_t m_semaphore;
|
||||
int semcount;
|
||||
#else
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
#undef sem_t
|
||||
#define sem_t semaphore_t
|
||||
#undef sem_init
|
||||
|
|
|
@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include "jthread/jsemaphore.h"
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
#undef sem_t
|
||||
#undef sem_init
|
||||
#undef sem_wait
|
||||
|
@ -44,7 +44,7 @@ JSemaphore::JSemaphore() {
|
|||
int sem_init_retval = sem_init(&m_semaphore,0,0);
|
||||
assert(sem_init_retval == 0);
|
||||
UNUSED(sem_init_retval);
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
semcount = 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ void JSemaphore::Post() {
|
|||
int sem_post_retval = sem_post(&m_semaphore);
|
||||
assert(sem_post_retval == 0);
|
||||
UNUSED(sem_post_retval);
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount++;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
|
@ -84,7 +84,7 @@ void JSemaphore::Wait() {
|
|||
int sem_wait_retval = sem_wait(&m_semaphore);
|
||||
assert(sem_wait_retval == 0);
|
||||
UNUSED(sem_wait_retval);
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount--;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
|
@ -92,7 +92,7 @@ void JSemaphore::Wait() {
|
|||
}
|
||||
|
||||
bool JSemaphore::Wait(unsigned int time_ms) {
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
mach_timespec_t waittime;
|
||||
waittime.tv_sec = time_ms / 1000;
|
||||
waittime.tv_nsec = 1000000 * (time_ms % 1000);
|
||||
|
@ -106,14 +106,14 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#if !(defined(__MACH__) && defined(__APPLE__))
|
||||
#ifndef __MACH__
|
||||
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_nsec %= 1000*1000*1000;
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
int sem_wait_retval = semaphore_timedwait(m_semaphore, waittime);
|
||||
if (sem_wait_retval == KERN_OPERATION_TIMED_OUT) {
|
||||
errno = ETIMEDOUT;
|
||||
|
@ -128,7 +128,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
|||
|
||||
if (sem_wait_retval == 0)
|
||||
{
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount--;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
|
@ -144,7 +144,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
|||
|
||||
int JSemaphore::GetValue() {
|
||||
int retval = 0;
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#ifdef __MACH__
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
retval = semcount;
|
||||
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 "settings.h"
|
||||
#include "log.h"
|
||||
#include "hex.h"
|
||||
#include "debug.h"
|
||||
#include "util/hex.h"
|
||||
|
||||
class UnknownKeycode : public BaseException
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ LocalPlayer::~LocalPlayer()
|
|||
}
|
||||
|
||||
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();
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
@ -323,8 +323,9 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||
*/
|
||||
bool bouncy_jump = false;
|
||||
// Dont report if flying
|
||||
if(collision_info && !(g_settings->getBool("free_move") && fly_allowed)) {
|
||||
for(size_t i=0; i<result.collisions.size(); i++) {
|
||||
if(collision_info && !(g_settings->getBool("free_move") && fly_allowed))
|
||||
{
|
||||
for(size_t i=0; i<result.collisions.size(); i++){
|
||||
const CollisionInfo &info = result.collisions[i];
|
||||
collision_info->push_back(info);
|
||||
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,
|
||||
std::vector<CollisionInfo> *collision_info);
|
||||
std::list<CollisionInfo> *collision_info);
|
||||
|
||||
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 <algorithm>
|
||||
#include "threads.h"
|
||||
#include "jthread/jmutexautolock.h"
|
||||
#include "debug.h"
|
||||
#include "gettime.h"
|
||||
#include "porting.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
unsigned int android_log_level_mapping[] = {
|
||||
unsigned int android_log_level_mapping[] {
|
||||
/* LMT_ERROR */ ANDROID_LOG_ERROR,
|
||||
/* LMT_ACTION */ ANDROID_LOG_WARN,
|
||||
/* LMT_INFO */ ANDROID_LOG_INFO,
|
||||
|
@ -39,7 +38,7 @@ unsigned int android_log_level_mapping[] = {
|
|||
};
|
||||
#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;
|
||||
JMutex log_threadnamemutex;
|
||||
|
||||
|
@ -63,7 +62,7 @@ void log_add_output_all_levs(ILogOutput *out)
|
|||
void log_remove_output(ILogOutput *out)
|
||||
{
|
||||
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);
|
||||
if(it != log_outputs[i].end())
|
||||
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)
|
||||
{
|
||||
JMutexAutoLock lock(log_threadnamemutex);
|
||||
log_threadnamemutex.Lock();
|
||||
|
||||
for (std::vector<ILogOutput *>::iterator it = log_outputs[lev].begin();
|
||||
it != log_outputs[lev].end(); ++it) {
|
||||
for (std::list<ILogOutput *>::iterator
|
||||
it = log_outputs[lev].begin();
|
||||
it != log_outputs[lev].end();
|
||||
++it) {
|
||||
ILogOutput *out = *it;
|
||||
out->silence = silence;
|
||||
}
|
||||
|
||||
log_threadnamemutex.Unlock();
|
||||
}
|
||||
|
||||
void log_register_thread(const std::string &name)
|
||||
{
|
||||
threadid_t id = get_current_thread_id();
|
||||
JMutexAutoLock lock(log_threadnamemutex);
|
||||
|
||||
log_threadnamemutex.Lock();
|
||||
log_threadnames[id] = name;
|
||||
log_threadnamemutex.Unlock();
|
||||
}
|
||||
|
||||
void log_deregister_thread()
|
||||
{
|
||||
threadid_t id = get_current_thread_id();
|
||||
JMutexAutoLock lock(log_threadnamemutex);
|
||||
|
||||
log_threadnamemutex.Lock();
|
||||
log_threadnames.erase(id);
|
||||
log_threadnamemutex.Unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
JMutexAutoLock lock(log_threadnamemutex);
|
||||
log_threadnamemutex.Lock();
|
||||
std::string threadname = "(unknown thread)";
|
||||
std::map<threadid_t, std::string>::const_iterator i;
|
||||
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;
|
||||
std::string levelname = get_lev_string(lev);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
os << getTimestamp() << ": " << levelname << "["<<threadname<<"]: " << text;
|
||||
|
||||
for(std::vector<ILogOutput*>::iterator i = log_outputs[lev].begin();
|
||||
i != log_outputs[lev].end(); i++) {
|
||||
os<<getTimestamp()<<": "<<levelname<<"["<<threadname<<"]: "<<text;
|
||||
for(std::list<ILogOutput*>::iterator i = log_outputs[lev].begin();
|
||||
i != log_outputs[lev].end(); i++){
|
||||
ILogOutput *out = *i;
|
||||
if (out->silence)
|
||||
continue;
|
||||
|
@ -136,6 +138,7 @@ void log_printline(enum LogMessageLevel lev, const std::string &text)
|
|||
out->printLog(os.str(), lev);
|
||||
out->printLog(lev, text);
|
||||
}
|
||||
log_threadnamemutex.Unlock();
|
||||
}
|
||||
|
||||
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