From 8a46c5df1c1b7d7c2b46b73f973a45388a517e71 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 26 Dec 2015 17:01:41 +0100 Subject: [PATCH 01/68] Database backends: fix bug, and small speedup -> Redis backend: break from switch to fix bug -> Dummy and redis backends: reserve the count so that creating the list is faster --- src/database-dummy.cpp | 1 + src/database-redis.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/database-dummy.cpp b/src/database-dummy.cpp index 2e5de5ed1..b38db1fb9 100644 --- a/src/database-dummy.cpp +++ b/src/database-dummy.cpp @@ -47,6 +47,7 @@ bool Database_Dummy::deleteBlock(const v3s16 &pos) void Database_Dummy::listAllLoadableBlocks(std::vector &dst) { + dst.reserve(m_database.size()); for (std::map::const_iterator x = m_database.begin(); x != m_database.end(); ++x) { dst.push_back(getIntegerAsBlock(x->first)); diff --git a/src/database-redis.cpp b/src/database-redis.cpp index b15f546b2..196d72f25 100644 --- a/src/database-redis.cpp +++ b/src/database-redis.cpp @@ -169,10 +169,12 @@ void Database_Redis::listAllLoadableBlocks(std::vector &dst) } switch (reply->type) { case REDIS_REPLY_ARRAY: + dst.reserve(reply->elements); 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))); } + break; case REDIS_REPLY_ERROR: throw FileNotGoodException(std::string( "Failed to get keys from database: ") + reply->str); From e2d54c9f9275e4f77ec33be8054621d42945f7a4 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 26 Dec 2015 16:19:09 +0100 Subject: [PATCH 02/68] shutdown when requested from lua in singleplayer too Before, minetest.request_shutdown didn't shut down singleplayer instances or server instances from the server tab. This commit fixes this. Fixes #3489. --- src/game.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game.cpp b/src/game.cpp index 3f025f6de..25424fa26 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1816,7 +1816,9 @@ void Game::run() && client->checkPrivilege("fast"); #endif - while (device->run() && !(*kill || g_gamecallback->shutdown_requested)) { + while (device->run() + && !(*kill || g_gamecallback->shutdown_requested + || server->getShutdownRequested())) { /* Must be called immediately after a device->run() call because it * uses device->getTimer()->getTime() From f14e7bac54af65e3d3d99f89f23f114b17058e49 Mon Sep 17 00:00:00 2001 From: Sapier Date: Sat, 19 Dec 2015 13:29:06 +0100 Subject: [PATCH 03/68] Refactoring and code style fixes in preparation of adding mesh typed items --- src/itemdef.cpp | 789 ++++++++++++++++++++++++------------------------ src/itemdef.h | 82 ++++- 2 files changed, 477 insertions(+), 394 deletions(-) diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 60a7dc64e..fa277f4ff 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -28,15 +28,10 @@ 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" #endif #include "log.h" #include "settings.h" #include "util/serialize.h" -#include "util/container.h" -#include "util/thread.h" -#include -#include #ifdef __ANDROID__ #include @@ -227,429 +222,437 @@ void ItemDefinition::deSerialize(std::istream &is) // SUGG: Support chains of aliases? -class CItemDefManager: public IWritableItemDefManager +#ifndef SERVER +CItemDefManager::ClientCached::ClientCached() : + inventory_texture(NULL), + wield_mesh(NULL) +{} +#endif + +CItemDefManager::CItemDefManager() { #ifndef SERVER - struct ClientCached - { - video::ITexture *inventory_texture; - scene::IMesh *wield_mesh; - - ClientCached(): - inventory_texture(NULL), - wield_mesh(NULL) - {} - }; + m_main_thread = thr_get_current_thread_id(); #endif + clear(); +} -public: - CItemDefManager() - { - +/******************************************************************************/ +CItemDefManager::~CItemDefManager() +{ #ifndef SERVER - m_main_thread = thr_get_current_thread_id(); -#endif - clear(); + const std::vector &values = m_clientcached.getValues(); + for(std::vector::const_iterator + i = values.begin(); i != values.end(); ++i) { + + ClientCached *cc = *i; + if (cc->wield_mesh) + cc->wield_mesh->drop(); + delete cc; } - virtual ~CItemDefManager() - { + +#endif + for (std::map::iterator iter = + m_item_definitions.begin(); iter != m_item_definitions.end(); + ++iter) { + + delete iter->second; + } + m_item_definitions.clear(); +} + +/******************************************************************************/ +const ItemDefinition& CItemDefManager::get(const std::string &name_) const +{ + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + i = m_item_definitions.find(name); + if(i == m_item_definitions.end()) + i = m_item_definitions.find("unknown"); + assert(i != m_item_definitions.end()); + return *(i->second); +} + +/******************************************************************************/ +std::string CItemDefManager::getAlias(const std::string &name) const +{ + StringMap::const_iterator it = m_aliases.find(name); + if (it != m_aliases.end()) + return it->second; + + return name; +} + +/******************************************************************************/ +std::set CItemDefManager::getAll() const +{ + std::set result; + for(std::map::const_iterator + it = m_item_definitions.begin(); + it != m_item_definitions.end(); ++it) { + + result.insert(it->first); + } + for (StringMap::const_iterator + it = m_aliases.begin(); + it != m_aliases.end(); ++it) { + + result.insert(it->first); + } + return result; +} + +/******************************************************************************/ +bool CItemDefManager::isKnown(const std::string &name_) const +{ + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + + return m_item_definitions.find(name) != m_item_definitions.end(); +} #ifndef SERVER - const std::vector &values = m_clientcached.getValues(); - for(std::vector::const_iterator - i = values.begin(); i != values.end(); ++i) - { - ClientCached *cc = *i; - if (cc->wield_mesh) - cc->wield_mesh->drop(); - delete cc; - } -#endif - for (std::map::iterator iter = - m_item_definitions.begin(); iter != m_item_definitions.end(); - ++iter) { - delete iter->second; - } - m_item_definitions.clear(); - } - virtual const ItemDefinition& get(const std::string &name_) const - { - // Convert name according to possible alias - std::string name = getAlias(name_); - // Get the definition - std::map::const_iterator i; - i = m_item_definitions.find(name); - if(i == m_item_definitions.end()) - i = m_item_definitions.find("unknown"); - assert(i != m_item_definitions.end()); - return *(i->second); - } - virtual std::string getAlias(const std::string &name) const - { - StringMap::const_iterator it = m_aliases.find(name); - if (it != m_aliases.end()) - return it->second; - return name; - } - virtual std::set getAll() const - { - std::set result; - for(std::map::const_iterator - it = m_item_definitions.begin(); - it != m_item_definitions.end(); ++it) { - result.insert(it->first); - } - for (StringMap::const_iterator - it = m_aliases.begin(); - it != m_aliases.end(); ++it) { - result.insert(it->first); - } - return result; - } - virtual bool isKnown(const std::string &name_) const - { - // Convert name according to possible alias - std::string name = getAlias(name_); - // Get the definition - std::map::const_iterator i; - return m_item_definitions.find(name) != m_item_definitions.end(); - } -#ifndef SERVER -public: - ClientCached* createClientCachedDirect(const std::string &name, - IGameDef *gamedef) const - { - infostream<<"Lazily creating item texture and mesh for \"" - <getTextureSource(); - INodeDefManager *nodedef = gamedef->getNodeDefManager(); - const ItemDefinition &def = get(name); - - // Create new ClientCached - cc = new ClientCached(); - - // Create an inventory texture - cc->inventory_texture = NULL; - if(def.inventory_image != "") - cc->inventory_texture = tsrc->getTexture(def.inventory_image); - - // Additional processing for nodes: - // - Create a wield mesh if WieldMeshSceneNode can't render - // the node on its own. - // - If inventory_texture isn't set yet, create one using - // render-to-texture. - if (def.type == ITEM_NODE) { - // Get node properties - content_t id = nodedef->getId(name); - const ContentFeatures &f = nodedef->get(id); - - bool need_rtt_mesh = cc->inventory_texture == NULL; - - // Keep this in sync with WieldMeshSceneNode::setItem() - bool need_wield_mesh = - !(f.mesh_ptr[0] || - f.drawtype == NDT_NORMAL || - f.drawtype == NDT_ALLFACES || - f.drawtype == NDT_AIRLIKE); - - scene::IMesh *node_mesh = NULL; - - if (need_rtt_mesh || need_wield_mesh) { - u8 param1 = 0; - if (f.param_type == CPT_LIGHT) - param1 = 0xee; - - /* - Make a mesh from the node - */ - MeshMakeData mesh_make_data(gamedef, false); - u8 param2 = 0; - if (f.param_type_2 == CPT2_WALLMOUNTED) - param2 = 1; - MapNode mesh_make_node(id, param1, param2); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - node_mesh = mapblock_mesh.getMesh(); - node_mesh->grab(); - video::SColor c(255, 255, 255, 255); - setMeshColor(node_mesh, c); - - // scale and translate the mesh so it's a - // unit cube centered on the origin - scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); - translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); - } - - /* - Draw node mesh into a render target texture - */ - if (need_rtt_mesh) { - TextureFromMeshParams params; - params.mesh = node_mesh; - params.dim.set(64, 64); - params.rtt_texture_name = "INVENTORY_" - + def.name + "_RTT"; - params.delete_texture_on_shutdown = true; - params.camera_position.set(0, 1.0, -1.5); - params.camera_position.rotateXZBy(45); - params.camera_lookat.set(0, 0, 0); - // Set orthogonal projection - params.camera_projection_matrix.buildProjectionMatrixOrthoLH( - 1.65, 1.65, 0, 100); - params.ambient_light.set(1.0, 0.2, 0.2, 0.2); - params.light_position.set(10, 100, -50); - params.light_color.set(1.0, 0.5, 0.5, 0.5); - params.light_radius = 1000; - -#ifdef __ANDROID__ - params.camera_position.set(0, -1.0, -1.5); - params.camera_position.rotateXZBy(45); - params.light_position.set(10, -100, -50); -#endif - cc->inventory_texture = - tsrc->generateTextureFromMesh(params); - - // render-to-target didn't work - if (cc->inventory_texture == NULL) { - cc->inventory_texture = - tsrc->getTexture(f.tiledef[0].name); - } - } - - /* - Use the node mesh as the wield mesh - */ - if (need_wield_mesh) { - cc->wield_mesh = node_mesh; - cc->wield_mesh->grab(); - - // no way reference count can be smaller than 2 in this place! - assert(cc->wield_mesh->getReferenceCount() >= 2); - } - - if (node_mesh) - node_mesh->drop(); - } - - // Put in cache - m_clientcached.set(name, cc); + // This is not thread-safe + sanity_check(thr_is_current_thread(m_main_thread)); + // Skip if already in cache + ClientCached *cc = NULL; + m_clientcached.get(name, &cc); + if (cc) return cc; + + ITextureSource *tsrc = gamedef->getTextureSource(); + INodeDefManager *nodedef = gamedef->getNodeDefManager(); + const ItemDefinition &def = get(name); + + // Create new ClientCached + cc = new ClientCached(); + + // Create an inventory texture + cc->inventory_texture = NULL; + if (def.inventory_image != "") + cc->inventory_texture = tsrc->getTexture(def.inventory_image); + + // Additional processing for nodes: + // - Create a wield mesh if WieldMeshSceneNode can't render + // the node on its own. + // - If inventory_texture isn't set yet, create one using + // render-to-texture. + if (def.type == ITEM_NODE) { + createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc); } - ClientCached* getClientCached(const std::string &name, - IGameDef *gamedef) const + + // Put in cache + m_clientcached.set(name, cc); + + return cc; +} + +/******************************************************************************/ +CItemDefManager::ClientCached* CItemDefManager::getClientCached(const std::string &name, + IGameDef *gamedef) const +{ + ClientCached *cc = NULL; + m_clientcached.get(name, &cc); + if (cc) + return cc; + + if (thr_is_current_thread(m_main_thread)) { + + return createClientCachedDirect(name, gamedef); + } + else { - ClientCached *cc = NULL; - m_clientcached.get(name, &cc); - if(cc) - return cc; + // We're gonna ask the result to be put into here + static ResultQueue result_queue; - if(thr_is_current_thread(m_main_thread)) - { - return createClientCachedDirect(name, gamedef); - } - else - { - // We're gonna ask the result to be put into here - static ResultQueue result_queue; + // Throw a request in + m_get_clientcached_queue.add(name, 0, 0, &result_queue); + try{ + while (true) { + // Wait result for a second + GetResult + result = result_queue.pop_front(1000); - // Throw a request in - m_get_clientcached_queue.add(name, 0, 0, &result_queue); - try{ - while(true) { - // Wait result for a second - GetResult - result = result_queue.pop_front(1000); - - if (result.key == name) { - return result.item; - } + if (result.key == name) { + return result.item; } } - catch(ItemNotFoundException &e) - { - errorstream<<"Waiting for clientcached " << name << " timed out."<inventory_texture; - } - // Get item wield mesh - virtual scene::IMesh* getWieldMesh(const std::string &name, - IGameDef *gamedef) const - { - ClientCached *cc = getClientCached(name, gamedef); - if(!cc) - return NULL; - return cc->wield_mesh; - } +} + +/******************************************************************************/ +// Get item inventory texture +video::ITexture* CItemDefManager::getInventoryTexture(const std::string &name, + IGameDef *gamedef) const +{ + ClientCached *cc = getClientCached(name, gamedef); + if (!cc) + return NULL; + + return cc->inventory_texture; +} + +/******************************************************************************/ +// Get item wield mesh +scene::IMesh* CItemDefManager::getWieldMesh(const std::string &name, + IGameDef *gamedef) const +{ + ClientCached *cc = getClientCached(name, gamedef); + if (!cc) + return NULL; + + return cc->wield_mesh; +} #endif - void clear() - { - for(std::map::const_iterator - i = m_item_definitions.begin(); - i != m_item_definitions.end(); ++i) - { - delete i->second; - } - m_item_definitions.clear(); - m_aliases.clear(); - // Add the four builtin items: - // "" is the hand - // "unknown" is returned whenever an undefined item - // is accessed (is also the unknown node) - // "air" is the air node - // "ignore" is the ignore node +/******************************************************************************/ +void CItemDefManager::clear() +{ + for (std::map::const_iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); ++i) { - ItemDefinition* hand_def = new ItemDefinition; - hand_def->name = ""; - hand_def->wield_image = "wieldhand.png"; - hand_def->tool_capabilities = new ToolCapabilities; - m_item_definitions.insert(std::make_pair("", hand_def)); - - ItemDefinition* unknown_def = new ItemDefinition; - unknown_def->type = ITEM_NODE; - unknown_def->name = "unknown"; - m_item_definitions.insert(std::make_pair("unknown", unknown_def)); - - ItemDefinition* air_def = new ItemDefinition; - air_def->type = ITEM_NODE; - air_def->name = "air"; - m_item_definitions.insert(std::make_pair("air", air_def)); - - ItemDefinition* ignore_def = new ItemDefinition; - ignore_def->type = ITEM_NODE; - ignore_def->name = "ignore"; - m_item_definitions.insert(std::make_pair("ignore", ignore_def)); + delete i->second; } - virtual void registerItem(const ItemDefinition &def) - { - verbosestream<<"ItemDefManager: registering \""<name = ""; + hand_def->wield_image = "wieldhand.png"; + hand_def->tool_capabilities = new ToolCapabilities; + m_item_definitions.insert(std::make_pair("", hand_def)); + + ItemDefinition* unknown_def = new ItemDefinition; + unknown_def->type = ITEM_NODE; + unknown_def->name = "unknown"; + m_item_definitions.insert(std::make_pair("unknown", unknown_def)); + + ItemDefinition* air_def = new ItemDefinition; + air_def->type = ITEM_NODE; + air_def->name = "air"; + m_item_definitions.insert(std::make_pair("air", air_def)); + + ItemDefinition* ignore_def = new ItemDefinition; + ignore_def->type = ITEM_NODE; + ignore_def->name = "ignore"; + m_item_definitions.insert(std::make_pair("ignore", ignore_def)); +} + +/******************************************************************************/ +void CItemDefManager::registerItem(const ItemDefinition &def) +{ + verbosestream<<"ItemDefManager: registering \""< "< "<::const_iterator - it = m_item_definitions.begin(); - it != m_item_definitions.end(); ++it) { - ItemDefinition *def = it->second; - // Serialize ItemDefinition and write wrapped in a string - std::ostringstream tmp_os(std::ios::binary); - def->serialize(tmp_os, protocol_version); - os << serializeString(tmp_os.str()); - } +/******************************************************************************/ +void CItemDefManager::serialize(std::ostream &os, u16 protocol_version) +{ + writeU8(os, 0); // version + u16 count = m_item_definitions.size(); + writeU16(os, count); - writeU16(os, m_aliases.size()); + for (std::map::const_iterator + it = m_item_definitions.begin(); + it != m_item_definitions.end(); ++it) { + ItemDefinition *def = it->second; + // Serialize ItemDefinition and write wrapped in a string + std::ostringstream tmp_os(std::ios::binary); + def->serialize(tmp_os, protocol_version); + os << serializeString(tmp_os.str()); + } - for (StringMap::const_iterator - it = m_aliases.begin(); - it != m_aliases.end(); ++it) { - os << serializeString(it->first); - os << serializeString(it->second); - } + writeU16(os, m_aliases.size()); + + for (StringMap::const_iterator + it = m_aliases.begin(); + it != m_aliases.end(); ++it) { + os << serializeString(it->first); + os << serializeString(it->second); } - void deSerialize(std::istream &is) - { - // Clear everything - clear(); - // Deserialize - int version = readU8(is); - if(version != 0) - throw SerializationError("unsupported ItemDefManager version"); - u16 count = readU16(is); - for(u16 i=0; i - request = m_get_clientcached_queue.pop(); + //NOTE this is only thread safe for ONE consumer thread! + while (!m_get_clientcached_queue.empty()) { - m_get_clientcached_queue.pushResult(request, - createClientCachedDirect(request.key, gamedef)); - } -#endif + GetRequest + request = m_get_clientcached_queue.pop(); + + m_get_clientcached_queue.pushResult(request, + createClientCachedDirect(request.key, gamedef)); } -private: - // Key is name - std::map m_item_definitions; - // Aliases - StringMap m_aliases; -#ifndef SERVER - // The id of the thread that is allowed to use irrlicht directly - threadid_t m_main_thread; - // A reference to this can be returned when nothing is found, to avoid NULLs - mutable ClientCached m_dummy_clientcached; - // Cached textures and meshes - mutable MutexedMap m_clientcached; - // Queued clientcached fetches (to be processed by the main thread) - mutable RequestQueue m_get_clientcached_queue; #endif -}; +} + +#ifndef SERVER +/******************************************************************************/ +void CItemDefManager::createNodeItemTexture(const std::string& name, + const ItemDefinition& def, INodeDefManager* nodedef, + ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const +{ + // Get node properties + content_t id = nodedef->getId(name); + const ContentFeatures& f = nodedef->get(id); + bool need_rtt_mesh = cc->inventory_texture == NULL; + // Keep this in sync with WieldMeshSceneNode::setItem() + bool need_wield_mesh = !(f.mesh_ptr[0] || f.drawtype == NDT_NORMAL + || f.drawtype == NDT_ALLFACES || f.drawtype == NDT_AIRLIKE); + scene::IMesh* node_mesh = NULL; + + if (need_rtt_mesh || need_wield_mesh) { + + u8 param1 = 0; + if (f.param_type == CPT_LIGHT) + param1 = 0xee; + + /* + Make a mesh from the node + */ + MeshMakeData mesh_make_data(gamedef, false); + u8 param2 = 0; + if (f.param_type_2 == CPT2_WALLMOUNTED) + param2 = 1; + + MapNode mesh_make_node(id, param1, param2); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + node_mesh = mapblock_mesh.getMesh(); + node_mesh->grab(); + video::SColor c(255, 255, 255, 255); + setMeshColor(node_mesh, c); + // scale and translate the mesh so it's a + // unit cube centered on the origin + scaleMesh(node_mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS)); + translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + } + /* + Draw node mesh into a render target texture + */ + if (need_rtt_mesh) { + + TextureFromMeshParams params; + params.mesh = node_mesh; + params.dim.set(64, 64); + params.rtt_texture_name = "INVENTORY_" + def.name + "_RTT"; + params.delete_texture_on_shutdown = true; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); + // Set orthogonal projection + params.camera_projection_matrix.buildProjectionMatrixOrthoLH(1.65, + 1.65, 0, 100); + params.ambient_light.set(1.0, 0.2, 0.2, 0.2); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; + cc->inventory_texture = tsrc->generateTextureFromMesh(params); + // render-to-target didn't work + if (cc->inventory_texture == NULL) { + + cc->inventory_texture = tsrc->getTexture(f.tiledef[0].name); + } + } + /* + Use the node mesh as the wield mesh + */ + if (need_wield_mesh) { + + cc->wield_mesh = node_mesh; + cc->wield_mesh->grab(); + // no way reference count can be smaller than 2 in this place! + assert(cc->wield_mesh->getReferenceCount() >= 2); + } + if (node_mesh) + node_mesh->drop(); +} +#endif + +/******************************************************************************/ IWritableItemDefManager* createItemDefManager() { diff --git a/src/itemdef.h b/src/itemdef.h index 805b4aa5d..fb157705f 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -25,9 +25,18 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include "itemgroup.h" #include "sound.h" +#include "util/container.h" +#include "util/thread.h" + +#ifndef SERVER +#include "client/tile.h" +#endif + class IGameDef; +class INodeDefManager; struct ToolCapabilities; /* @@ -39,7 +48,7 @@ enum ItemType ITEM_NONE, ITEM_NODE, ITEM_CRAFT, - ITEM_TOOL, + ITEM_TOOL }; struct ItemDefinition @@ -157,6 +166,77 @@ public: virtual void processQueue(IGameDef *gamedef)=0; }; + +class CItemDefManager: public IWritableItemDefManager +{ +public: + CItemDefManager(); + virtual ~CItemDefManager(); + virtual const ItemDefinition& get(const std::string &name_) const; + virtual std::string getAlias(const std::string &name) const; + virtual std::set getAll() const; + virtual bool isKnown(const std::string &name_) const; + +#ifndef SERVER + // Get item inventory texture + virtual video::ITexture* getInventoryTexture(const std::string &name, + IGameDef *gamedef) const; + + // Get item wield mesh + virtual scene::IMesh* getWieldMesh(const std::string &name, + IGameDef *gamedef) const; +#endif + void clear(); + + virtual void registerItem(const ItemDefinition &def); + virtual void registerAlias(const std::string &name, + const std::string &convert_to); + void serialize(std::ostream &os, u16 protocol_version); + void deSerialize(std::istream &is); + + void processQueue(IGameDef *gamedef); + +private: + +#ifndef SERVER + struct ClientCached + { + video::ITexture *inventory_texture; + scene::IMesh *wield_mesh; + + ClientCached(); + }; + + void createNodeItemTexture(const std::string& name, + const ItemDefinition& def, INodeDefManager* nodedef, + ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const; + + ClientCached* createClientCachedDirect(const std::string &name, + IGameDef *gamedef) const; + + ClientCached* getClientCached(const std::string &name, + IGameDef *gamedef) const; + + // The id of the thread that is allowed to use irrlicht directly + threadid_t m_main_thread; + + // A reference to this can be returned when nothing is found, to avoid NULLs + mutable ClientCached m_dummy_clientcached; + + // Cached textures and meshes + mutable MutexedMap m_clientcached; + + // Queued clientcached fetches (to be processed by the main thread) + mutable RequestQueue m_get_clientcached_queue; +#endif + + // Key is name + std::map m_item_definitions; + + // Aliases + std::map m_aliases; +}; + IWritableItemDefManager* createItemDefManager(); #endif From 91bafceee6606fab79db1bde4cba01b84fed65c7 Mon Sep 17 00:00:00 2001 From: Sapier Date: Sat, 19 Dec 2015 04:43:59 +0100 Subject: [PATCH 04/68] Add support for using arbitrary meshes as items --- src/content_cao.cpp | 59 ++++++++++++++--- src/itemdef.cpp | 110 +++++++++++++++++++++++++++++++- src/itemdef.h | 9 +++ src/script/common/c_content.cpp | 2 + src/wieldmesh.cpp | 14 ++++ 5 files changed, 185 insertions(+), 9 deletions(-) diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 1b8e84c8f..bde0dd320 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -954,15 +954,43 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IItemDefManager *idef = m_gamedef->idef(); ItemStack item(m_prop.textures[0], 1, 0, "", idef); - m_wield_meshnode = new WieldMeshSceneNode( - smgr->getRootSceneNode(), smgr, -1); - m_wield_meshnode->setItem(item, m_gamedef); + if (!item.getDefinition(idef).meshname.empty()) + { + scene::IAnimatedMesh *mesh = m_gamedef->getMesh(item.getDefinition(idef).meshname); + if(mesh) + { + m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL); - m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, - m_prop.visual_size.Y/2, - m_prop.visual_size.X/2)); - u8 li = m_last_light; - m_wield_meshnode->setColor(video::SColor(255,li,li,li)); + m_animated_meshnode->grab(); + mesh->drop(); // The scene node took hold of it + m_animated_meshnode->animateJoints(); // Needed for some animations + m_animated_meshnode->setScale(v3f(m_prop.visual_size.X, + m_prop.visual_size.Y, + m_prop.visual_size.X)); + u8 li = m_last_light; + setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); + + bool backface_culling = m_prop.backface_culling; + if (m_is_player) + backface_culling = false; + + m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); + m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, backface_culling); + } + } + else { + m_wield_meshnode = new WieldMeshSceneNode( + smgr->getRootSceneNode(), smgr, -1); + m_wield_meshnode->setItem(item, m_gamedef); + m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, + m_prop.visual_size.Y/2, + m_prop.visual_size.X/2)); + u8 li = m_last_light; + m_wield_meshnode->setColor(video::SColor(255,li,li,li)); + } } } else { infostream<<"GenericCAO::addToScene(): \""<getMaterial(i).SpecularColor = m_prop.colors[i]; } } + else if (m_prop.visual == "wielditem") { + IItemDefManager *idef = m_gamedef->idef(); + ItemStack item(m_prop.textures[0], 1, 0, "", idef); + + if (!item.getDefinition(idef).meshname.empty()) { + + unsigned int materialcount = m_animated_meshnode->getMaterialCount(); + + for (unsigned int i = 0; i < materialcount; i++) { + m_animated_meshnode->getMaterial(i) + .setTexture(0, tsrc->getTexture(item + .getDefinition(idef).meshtexture)); + } + } + } } if(m_meshnode) { diff --git a/src/itemdef.cpp b/src/itemdef.cpp index fa277f4ff..e37f10d61 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -77,6 +77,8 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) sound_place = def.sound_place; sound_place_failed = def.sound_place_failed; range = def.range; + meshname = def.meshname; + meshtexture = def.meshtexture; return *this; } @@ -157,6 +159,10 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const os << serializeString(sound_place_failed.name); writeF1000(os, sound_place_failed.gain); } + + //TODO check for protocol version? + os<inventory_texture = NULL; - if (def.inventory_image != "") + if (!def.inventory_image.empty()) cc->inventory_texture = tsrc->getTexture(def.inventory_image); // Additional processing for nodes: @@ -352,6 +362,10 @@ CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const s if (def.type == ITEM_NODE) { createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc); } + else if (def.type == ITEM_CRAFT) { + if ( !def.meshname.empty()) + createMeshItemTexture(name, def, nodedef, cc, gamedef, tsrc); + } // Put in cache m_clientcached.set(name, cc); @@ -650,6 +664,100 @@ void CItemDefManager::createNodeItemTexture(const std::string& name, if (node_mesh) node_mesh->drop(); } + +/******************************************************************************/ +void CItemDefManager::renderMeshToTexture(const ItemDefinition& def, scene::IMesh* mesh, + ClientCached* cc, ITextureSource* tsrc) const +{ + video::ITexture *itemimage = cc->inventory_texture; + + /* + Draw node mesh into a render target texture + */ + TextureFromMeshParams params; + params.mesh = mesh; + params.dim.set(64, 64); + params.rtt_texture_name = "INVENTORY_" + def.name + "_RTT"; + params.delete_texture_on_shutdown = true; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); + // Set orthogonal projection + params.camera_projection_matrix.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, + 100); + params.ambient_light.set(1.0, 0.9, 0.9, 0.9); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; + cc->inventory_texture = tsrc->generateTextureFromMesh(params); + + // render-to-target didn't work + if (cc->inventory_texture == NULL) { + + cc->inventory_texture = itemimage; + } +} + +/******************************************************************************/ +void CItemDefManager::createMeshItemTexture(const std::string& name, + const ItemDefinition& def, INodeDefManager* nodedef, + ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const +{ + // Get node properties + content_t id = nodedef->getId(name); + const ContentFeatures& f = nodedef->get(id); + + if (def.meshname == "") + return; + + video::ITexture *texture = tsrc->getTexture(def.meshtexture); + + infostream<<"CItemDefManager::createMeshItemTexture(): mesh"<getMesh(def.meshname); + if(mesh) + { + + video::SColor c(255, 255, 255, 255); + setMeshColor(mesh, c); + + rotateMeshXZby(mesh, 180); + + // scale and translate the mesh so it's a + // unit cube centered on the origin + scaleMesh(mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS)); + + // Customize materials + for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { + + video::SMaterial &material = mesh->getMeshBuffer(i)->getMaterial(); + material.setTexture(0, texture); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + } + + /* + Draw node mesh into a render target texture + */ + renderMeshToTexture(def, mesh, cc, tsrc); + + /* + Use the ingot mesh as the wield mesh + */ + + cc->wield_mesh = mesh; + cc->wield_mesh->grab(); + // no way reference count can be smaller than 2 in this place! + assert(cc->wield_mesh->getReferenceCount() >= 2); + + if (mesh) + mesh->drop(); + + } + else + errorstream<<"CItemDefManager::createMeshItemTexture(): Could not load mesh "<getWieldMesh(def.name, gamedef) != 0) { + irr::scene::IMesh * mesh = idef->getWieldMesh(def.name, gamedef); + m_meshnode->setMesh(mesh); + u32 material_count = m_meshnode->getMaterialCount(); + for (u32 i = 0; i < material_count; ++i) { + video::SMaterial &material = m_meshnode->getMaterial(i); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); + material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); + material.MaterialType = m_material_type; + material.setTexture(0, tsrc->getTexture(def.meshtexture)); + } + return; + } else if (def.inventory_image != "") { setExtruded(def.inventory_image, def.wield_scale, tsrc, 1); return; From 61cb4d52a6873a0af69bb8c9a295586f09b2c27a Mon Sep 17 00:00:00 2001 From: Sapier Date: Fri, 18 Dec 2015 19:20:06 +0100 Subject: [PATCH 05/68] Make collisionMoveSimple time overflow message written to log/show up at max once per step --- src/collision.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/collision.cpp b/src/collision.cpp index 2b64547c3..187df0a5d 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -199,18 +199,25 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, v3f &accel_f,ActiveObject* self, bool collideWithObjects) { + static bool time_notification_done = false; Map *map = &env->getMap(); //TimeTaker tt("collisionMoveSimple"); - ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG); + ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG); collisionMoveResult result; /* Calculate new velocity */ - if( dtime > 0.5 ) { - warningstream<<"collisionMoveSimple: maximum step interval exceeded, lost movement details!"< 0.5) { + if (!time_notification_done) { + time_notification_done = true; + infostream << "collisionMoveSimple: maximum step interval exceeded," + " lost movement details!"< Date: Tue, 29 Dec 2015 19:53:38 +0100 Subject: [PATCH 06/68] Revert "Add support for using arbitrary meshes as items" This reverts commit 91bafceee6606fab79db1bde4cba01b84fed65c7. Reverted due to missinterpretation of agreement, obvious dislike and me not interested in doing fights for feature I don't actually need --- src/content_cao.cpp | 59 +++-------------- src/itemdef.cpp | 110 +------------------------------- src/itemdef.h | 9 --- src/script/common/c_content.cpp | 2 - src/wieldmesh.cpp | 14 ---- 5 files changed, 9 insertions(+), 185 deletions(-) diff --git a/src/content_cao.cpp b/src/content_cao.cpp index bde0dd320..1b8e84c8f 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -954,43 +954,15 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IItemDefManager *idef = m_gamedef->idef(); ItemStack item(m_prop.textures[0], 1, 0, "", idef); - if (!item.getDefinition(idef).meshname.empty()) - { - scene::IAnimatedMesh *mesh = m_gamedef->getMesh(item.getDefinition(idef).meshname); - if(mesh) - { - m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL); + m_wield_meshnode = new WieldMeshSceneNode( + smgr->getRootSceneNode(), smgr, -1); + m_wield_meshnode->setItem(item, m_gamedef); - m_animated_meshnode->grab(); - mesh->drop(); // The scene node took hold of it - m_animated_meshnode->animateJoints(); // Needed for some animations - m_animated_meshnode->setScale(v3f(m_prop.visual_size.X, - m_prop.visual_size.Y, - m_prop.visual_size.X)); - u8 li = m_last_light; - setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); - - bool backface_culling = m_prop.backface_culling; - if (m_is_player) - backface_culling = false; - - m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); - m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); - m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); - m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, backface_culling); - } - } - else { - m_wield_meshnode = new WieldMeshSceneNode( - smgr->getRootSceneNode(), smgr, -1); - m_wield_meshnode->setItem(item, m_gamedef); - m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, - m_prop.visual_size.Y/2, - m_prop.visual_size.X/2)); - u8 li = m_last_light; - m_wield_meshnode->setColor(video::SColor(255,li,li,li)); - } + m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, + m_prop.visual_size.Y/2, + m_prop.visual_size.X/2)); + u8 li = m_last_light; + m_wield_meshnode->setColor(video::SColor(255,li,li,li)); } } else { infostream<<"GenericCAO::addToScene(): \""<getMaterial(i).SpecularColor = m_prop.colors[i]; } } - else if (m_prop.visual == "wielditem") { - IItemDefManager *idef = m_gamedef->idef(); - ItemStack item(m_prop.textures[0], 1, 0, "", idef); - - if (!item.getDefinition(idef).meshname.empty()) { - - unsigned int materialcount = m_animated_meshnode->getMaterialCount(); - - for (unsigned int i = 0; i < materialcount; i++) { - m_animated_meshnode->getMaterial(i) - .setTexture(0, tsrc->getTexture(item - .getDefinition(idef).meshtexture)); - } - } - } } if(m_meshnode) { diff --git a/src/itemdef.cpp b/src/itemdef.cpp index e37f10d61..fa277f4ff 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -77,8 +77,6 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) sound_place = def.sound_place; sound_place_failed = def.sound_place_failed; range = def.range; - meshname = def.meshname; - meshtexture = def.meshtexture; return *this; } @@ -159,10 +157,6 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const os << serializeString(sound_place_failed.name); writeF1000(os, sound_place_failed.gain); } - - //TODO check for protocol version? - os<inventory_texture = NULL; - if (!def.inventory_image.empty()) + if (def.inventory_image != "") cc->inventory_texture = tsrc->getTexture(def.inventory_image); // Additional processing for nodes: @@ -362,10 +352,6 @@ CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const s if (def.type == ITEM_NODE) { createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc); } - else if (def.type == ITEM_CRAFT) { - if ( !def.meshname.empty()) - createMeshItemTexture(name, def, nodedef, cc, gamedef, tsrc); - } // Put in cache m_clientcached.set(name, cc); @@ -664,100 +650,6 @@ void CItemDefManager::createNodeItemTexture(const std::string& name, if (node_mesh) node_mesh->drop(); } - -/******************************************************************************/ -void CItemDefManager::renderMeshToTexture(const ItemDefinition& def, scene::IMesh* mesh, - ClientCached* cc, ITextureSource* tsrc) const -{ - video::ITexture *itemimage = cc->inventory_texture; - - /* - Draw node mesh into a render target texture - */ - TextureFromMeshParams params; - params.mesh = mesh; - params.dim.set(64, 64); - params.rtt_texture_name = "INVENTORY_" + def.name + "_RTT"; - params.delete_texture_on_shutdown = true; - params.camera_position.set(0, 1.0, -1.5); - params.camera_position.rotateXZBy(45); - params.camera_lookat.set(0, 0, 0); - // Set orthogonal projection - params.camera_projection_matrix.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, - 100); - params.ambient_light.set(1.0, 0.9, 0.9, 0.9); - params.light_position.set(10, 100, -50); - params.light_color.set(1.0, 0.5, 0.5, 0.5); - params.light_radius = 1000; - cc->inventory_texture = tsrc->generateTextureFromMesh(params); - - // render-to-target didn't work - if (cc->inventory_texture == NULL) { - - cc->inventory_texture = itemimage; - } -} - -/******************************************************************************/ -void CItemDefManager::createMeshItemTexture(const std::string& name, - const ItemDefinition& def, INodeDefManager* nodedef, - ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const -{ - // Get node properties - content_t id = nodedef->getId(name); - const ContentFeatures& f = nodedef->get(id); - - if (def.meshname == "") - return; - - video::ITexture *texture = tsrc->getTexture(def.meshtexture); - - infostream<<"CItemDefManager::createMeshItemTexture(): mesh"<getMesh(def.meshname); - if(mesh) - { - - video::SColor c(255, 255, 255, 255); - setMeshColor(mesh, c); - - rotateMeshXZby(mesh, 180); - - // scale and translate the mesh so it's a - // unit cube centered on the origin - scaleMesh(mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS)); - - // Customize materials - for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { - - video::SMaterial &material = mesh->getMeshBuffer(i)->getMaterial(); - material.setTexture(0, texture); - material.setFlag(video::EMF_BACK_FACE_CULLING, true); - material.setFlag(video::EMF_BILINEAR_FILTER, false); - material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - } - - /* - Draw node mesh into a render target texture - */ - renderMeshToTexture(def, mesh, cc, tsrc); - - /* - Use the ingot mesh as the wield mesh - */ - - cc->wield_mesh = mesh; - cc->wield_mesh->grab(); - // no way reference count can be smaller than 2 in this place! - assert(cc->wield_mesh->getReferenceCount() >= 2); - - if (mesh) - mesh->drop(); - - } - else - errorstream<<"CItemDefManager::createMeshItemTexture(): Could not load mesh "<getWieldMesh(def.name, gamedef) != 0) { - irr::scene::IMesh * mesh = idef->getWieldMesh(def.name, gamedef); - m_meshnode->setMesh(mesh); - u32 material_count = m_meshnode->getMaterialCount(); - for (u32 i = 0; i < material_count; ++i) { - video::SMaterial &material = m_meshnode->getMaterial(i); - material.setFlag(video::EMF_BACK_FACE_CULLING, true); - material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); - material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); - material.MaterialType = m_material_type; - material.setTexture(0, tsrc->getTexture(def.meshtexture)); - } - return; - } else if (def.inventory_image != "") { setExtruded(def.inventory_image, def.wield_scale, tsrc, 1); return; From 1735c20549d474a45f1f231ea7d25ff8e3157818 Mon Sep 17 00:00:00 2001 From: Sapier Date: Tue, 29 Dec 2015 19:55:50 +0100 Subject: [PATCH 07/68] Revert "Refactoring and code style fixes in preparation of adding mesh typed items" This reverts commit f14e7bac54af65e3d3d99f89f23f114b17058e49. Reverted due to missinterpretation of agreement, obvious dislike and me not interested in doing fights for feature I don't actually need --- src/itemdef.cpp | 805 ++++++++++++++++++++++++------------------------ src/itemdef.h | 82 +---- 2 files changed, 402 insertions(+), 485 deletions(-) diff --git a/src/itemdef.cpp b/src/itemdef.cpp index fa277f4ff..60a7dc64e 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -28,10 +28,15 @@ 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" #endif #include "log.h" #include "settings.h" #include "util/serialize.h" +#include "util/container.h" +#include "util/thread.h" +#include +#include #ifdef __ANDROID__ #include @@ -222,437 +227,429 @@ void ItemDefinition::deSerialize(std::istream &is) // SUGG: Support chains of aliases? -#ifndef SERVER -CItemDefManager::ClientCached::ClientCached() : - inventory_texture(NULL), - wield_mesh(NULL) -{} -#endif - -CItemDefManager::CItemDefManager() +class CItemDefManager: public IWritableItemDefManager { #ifndef SERVER - m_main_thread = thr_get_current_thread_id(); -#endif - clear(); -} - -/******************************************************************************/ -CItemDefManager::~CItemDefManager() -{ -#ifndef SERVER - const std::vector &values = m_clientcached.getValues(); - for(std::vector::const_iterator - i = values.begin(); i != values.end(); ++i) { - - ClientCached *cc = *i; - if (cc->wield_mesh) - cc->wield_mesh->drop(); - delete cc; - } - -#endif - for (std::map::iterator iter = - m_item_definitions.begin(); iter != m_item_definitions.end(); - ++iter) { - - delete iter->second; - } - m_item_definitions.clear(); -} - -/******************************************************************************/ -const ItemDefinition& CItemDefManager::get(const std::string &name_) const -{ - // Convert name according to possible alias - std::string name = getAlias(name_); - // Get the definition - std::map::const_iterator i; - i = m_item_definitions.find(name); - if(i == m_item_definitions.end()) - i = m_item_definitions.find("unknown"); - assert(i != m_item_definitions.end()); - return *(i->second); -} - -/******************************************************************************/ -std::string CItemDefManager::getAlias(const std::string &name) const -{ - StringMap::const_iterator it = m_aliases.find(name); - if (it != m_aliases.end()) - return it->second; - - return name; -} - -/******************************************************************************/ -std::set CItemDefManager::getAll() const -{ - std::set result; - for(std::map::const_iterator - it = m_item_definitions.begin(); - it != m_item_definitions.end(); ++it) { - - result.insert(it->first); - } - for (StringMap::const_iterator - it = m_aliases.begin(); - it != m_aliases.end(); ++it) { - - result.insert(it->first); - } - return result; -} - -/******************************************************************************/ -bool CItemDefManager::isKnown(const std::string &name_) const -{ - // Convert name according to possible alias - std::string name = getAlias(name_); - // Get the definition - std::map::const_iterator i; - - return m_item_definitions.find(name) != m_item_definitions.end(); -} -#ifndef SERVER - -/******************************************************************************/ -CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const std::string &name, - IGameDef *gamedef) const -{ - infostream<<"Lazily creating item texture and mesh for \"" - <getTextureSource(); - INodeDefManager *nodedef = gamedef->getNodeDefManager(); - const ItemDefinition &def = get(name); - - // Create new ClientCached - cc = new ClientCached(); - - // Create an inventory texture - cc->inventory_texture = NULL; - if (def.inventory_image != "") - cc->inventory_texture = tsrc->getTexture(def.inventory_image); - - // Additional processing for nodes: - // - Create a wield mesh if WieldMeshSceneNode can't render - // the node on its own. - // - If inventory_texture isn't set yet, create one using - // render-to-texture. - if (def.type == ITEM_NODE) { - createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc); - } - - // Put in cache - m_clientcached.set(name, cc); - - return cc; -} - -/******************************************************************************/ -CItemDefManager::ClientCached* CItemDefManager::getClientCached(const std::string &name, - IGameDef *gamedef) const -{ - ClientCached *cc = NULL; - m_clientcached.get(name, &cc); - if (cc) - return cc; - - if (thr_is_current_thread(m_main_thread)) { - - return createClientCachedDirect(name, gamedef); - } - else + struct ClientCached { - // We're gonna ask the result to be put into here - static ResultQueue result_queue; + video::ITexture *inventory_texture; + scene::IMesh *wield_mesh; - // Throw a request in - m_get_clientcached_queue.add(name, 0, 0, &result_queue); - try{ - while (true) { - // Wait result for a second - GetResult - result = result_queue.pop_front(1000); + ClientCached(): + inventory_texture(NULL), + wield_mesh(NULL) + {} + }; +#endif - if (result.key == name) { - return result.item; +public: + CItemDefManager() + { + +#ifndef SERVER + m_main_thread = thr_get_current_thread_id(); +#endif + clear(); + } + virtual ~CItemDefManager() + { +#ifndef SERVER + const std::vector &values = m_clientcached.getValues(); + for(std::vector::const_iterator + i = values.begin(); i != values.end(); ++i) + { + ClientCached *cc = *i; + if (cc->wield_mesh) + cc->wield_mesh->drop(); + delete cc; + } + +#endif + for (std::map::iterator iter = + m_item_definitions.begin(); iter != m_item_definitions.end(); + ++iter) { + delete iter->second; + } + m_item_definitions.clear(); + } + virtual const ItemDefinition& get(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + i = m_item_definitions.find(name); + if(i == m_item_definitions.end()) + i = m_item_definitions.find("unknown"); + assert(i != m_item_definitions.end()); + return *(i->second); + } + virtual std::string getAlias(const std::string &name) const + { + StringMap::const_iterator it = m_aliases.find(name); + if (it != m_aliases.end()) + return it->second; + return name; + } + virtual std::set getAll() const + { + std::set result; + for(std::map::const_iterator + it = m_item_definitions.begin(); + it != m_item_definitions.end(); ++it) { + result.insert(it->first); + } + for (StringMap::const_iterator + it = m_aliases.begin(); + it != m_aliases.end(); ++it) { + result.insert(it->first); + } + return result; + } + virtual bool isKnown(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + return m_item_definitions.find(name) != m_item_definitions.end(); + } +#ifndef SERVER +public: + ClientCached* createClientCachedDirect(const std::string &name, + IGameDef *gamedef) const + { + infostream<<"Lazily creating item texture and mesh for \"" + <getTextureSource(); + INodeDefManager *nodedef = gamedef->getNodeDefManager(); + const ItemDefinition &def = get(name); + + // Create new ClientCached + cc = new ClientCached(); + + // Create an inventory texture + cc->inventory_texture = NULL; + if(def.inventory_image != "") + cc->inventory_texture = tsrc->getTexture(def.inventory_image); + + // Additional processing for nodes: + // - Create a wield mesh if WieldMeshSceneNode can't render + // the node on its own. + // - If inventory_texture isn't set yet, create one using + // render-to-texture. + if (def.type == ITEM_NODE) { + // Get node properties + content_t id = nodedef->getId(name); + const ContentFeatures &f = nodedef->get(id); + + bool need_rtt_mesh = cc->inventory_texture == NULL; + + // Keep this in sync with WieldMeshSceneNode::setItem() + bool need_wield_mesh = + !(f.mesh_ptr[0] || + f.drawtype == NDT_NORMAL || + f.drawtype == NDT_ALLFACES || + f.drawtype == NDT_AIRLIKE); + + scene::IMesh *node_mesh = NULL; + + if (need_rtt_mesh || need_wield_mesh) { + u8 param1 = 0; + if (f.param_type == CPT_LIGHT) + param1 = 0xee; + + /* + Make a mesh from the node + */ + MeshMakeData mesh_make_data(gamedef, false); + u8 param2 = 0; + if (f.param_type_2 == CPT2_WALLMOUNTED) + param2 = 1; + MapNode mesh_make_node(id, param1, param2); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + node_mesh = mapblock_mesh.getMesh(); + node_mesh->grab(); + video::SColor c(255, 255, 255, 255); + setMeshColor(node_mesh, c); + + // scale and translate the mesh so it's a + // unit cube centered on the origin + scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); + translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + } + + /* + Draw node mesh into a render target texture + */ + if (need_rtt_mesh) { + TextureFromMeshParams params; + params.mesh = node_mesh; + params.dim.set(64, 64); + params.rtt_texture_name = "INVENTORY_" + + def.name + "_RTT"; + params.delete_texture_on_shutdown = true; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); + // Set orthogonal projection + params.camera_projection_matrix.buildProjectionMatrixOrthoLH( + 1.65, 1.65, 0, 100); + params.ambient_light.set(1.0, 0.2, 0.2, 0.2); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; + +#ifdef __ANDROID__ + params.camera_position.set(0, -1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.light_position.set(10, -100, -50); +#endif + cc->inventory_texture = + tsrc->generateTextureFromMesh(params); + + // render-to-target didn't work + if (cc->inventory_texture == NULL) { + cc->inventory_texture = + tsrc->getTexture(f.tiledef[0].name); } } + + /* + Use the node mesh as the wield mesh + */ + if (need_wield_mesh) { + cc->wield_mesh = node_mesh; + cc->wield_mesh->grab(); + + // no way reference count can be smaller than 2 in this place! + assert(cc->wield_mesh->getReferenceCount() >= 2); + } + + if (node_mesh) + node_mesh->drop(); } - catch(ItemNotFoundException &e) + + // Put in cache + m_clientcached.set(name, cc); + + return cc; + } + ClientCached* getClientCached(const std::string &name, + IGameDef *gamedef) const + { + ClientCached *cc = NULL; + m_clientcached.get(name, &cc); + if(cc) + return cc; + + if(thr_is_current_thread(m_main_thread)) { - errorstream<<"Waiting for clientcached " << name << " timed out."< result_queue; + + // Throw a request in + m_get_clientcached_queue.add(name, 0, 0, &result_queue); + try{ + while(true) { + // Wait result for a second + GetResult + result = result_queue.pop_front(1000); + + if (result.key == name) { + return result.item; + } + } + } + catch(ItemNotFoundException &e) + { + errorstream<<"Waiting for clientcached " << name << " timed out."<inventory_texture; -} - -/******************************************************************************/ -// Get item wield mesh -scene::IMesh* CItemDefManager::getWieldMesh(const std::string &name, - IGameDef *gamedef) const -{ - ClientCached *cc = getClientCached(name, gamedef); - if (!cc) - return NULL; - - return cc->wield_mesh; -} -#endif - -/******************************************************************************/ -void CItemDefManager::clear() -{ - for (std::map::const_iterator - i = m_item_definitions.begin(); - i != m_item_definitions.end(); ++i) { - - delete i->second; + // Get item inventory texture + virtual video::ITexture* getInventoryTexture(const std::string &name, + IGameDef *gamedef) const + { + ClientCached *cc = getClientCached(name, gamedef); + if(!cc) + return NULL; + return cc->inventory_texture; } - m_item_definitions.clear(); - m_aliases.clear(); - - // Add the four builtin items: - // "" is the hand - // "unknown" is returned whenever an undefined item - // is accessed (is also the unknown node) - // "air" is the air node - // "ignore" is the ignore node - - ItemDefinition* hand_def = new ItemDefinition; - hand_def->name = ""; - hand_def->wield_image = "wieldhand.png"; - hand_def->tool_capabilities = new ToolCapabilities; - m_item_definitions.insert(std::make_pair("", hand_def)); - - ItemDefinition* unknown_def = new ItemDefinition; - unknown_def->type = ITEM_NODE; - unknown_def->name = "unknown"; - m_item_definitions.insert(std::make_pair("unknown", unknown_def)); - - ItemDefinition* air_def = new ItemDefinition; - air_def->type = ITEM_NODE; - air_def->name = "air"; - m_item_definitions.insert(std::make_pair("air", air_def)); - - ItemDefinition* ignore_def = new ItemDefinition; - ignore_def->type = ITEM_NODE; - ignore_def->name = "ignore"; - m_item_definitions.insert(std::make_pair("ignore", ignore_def)); -} - -/******************************************************************************/ -void CItemDefManager::registerItem(const ItemDefinition &def) -{ - verbosestream<<"ItemDefManager: registering \""< "<::const_iterator - it = m_item_definitions.begin(); - it != m_item_definitions.end(); ++it) { - ItemDefinition *def = it->second; - // Serialize ItemDefinition and write wrapped in a string - std::ostringstream tmp_os(std::ios::binary); - def->serialize(tmp_os, protocol_version); - os << serializeString(tmp_os.str()); - } - - writeU16(os, m_aliases.size()); - - for (StringMap::const_iterator - it = m_aliases.begin(); - it != m_aliases.end(); ++it) { - os << serializeString(it->first); - os << serializeString(it->second); - } -} - -/******************************************************************************/ -void CItemDefManager::deSerialize(std::istream &is) -{ - // Clear everything - clear(); - // Deserialize - int version = readU8(is); - if(version != 0) - throw SerializationError("unsupported ItemDefManager version"); - u16 count = readU16(is); - - for (u16 i=0; i - request = m_get_clientcached_queue.pop(); - - m_get_clientcached_queue.pushResult(request, - createClientCachedDirect(request.key, gamedef)); + // Get item wield mesh + virtual scene::IMesh* getWieldMesh(const std::string &name, + IGameDef *gamedef) const + { + ClientCached *cc = getClientCached(name, gamedef); + if(!cc) + return NULL; + return cc->wield_mesh; } #endif -} + void clear() + { + for(std::map::const_iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); ++i) + { + delete i->second; + } + m_item_definitions.clear(); + m_aliases.clear(); -#ifndef SERVER -/******************************************************************************/ -void CItemDefManager::createNodeItemTexture(const std::string& name, - const ItemDefinition& def, INodeDefManager* nodedef, - ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const -{ - // Get node properties - content_t id = nodedef->getId(name); - const ContentFeatures& f = nodedef->get(id); - bool need_rtt_mesh = cc->inventory_texture == NULL; - // Keep this in sync with WieldMeshSceneNode::setItem() - bool need_wield_mesh = !(f.mesh_ptr[0] || f.drawtype == NDT_NORMAL - || f.drawtype == NDT_ALLFACES || f.drawtype == NDT_AIRLIKE); - scene::IMesh* node_mesh = NULL; + // Add the four builtin items: + // "" is the hand + // "unknown" is returned whenever an undefined item + // is accessed (is also the unknown node) + // "air" is the air node + // "ignore" is the ignore node - if (need_rtt_mesh || need_wield_mesh) { + ItemDefinition* hand_def = new ItemDefinition; + hand_def->name = ""; + hand_def->wield_image = "wieldhand.png"; + hand_def->tool_capabilities = new ToolCapabilities; + m_item_definitions.insert(std::make_pair("", hand_def)); - u8 param1 = 0; - if (f.param_type == CPT_LIGHT) - param1 = 0xee; + ItemDefinition* unknown_def = new ItemDefinition; + unknown_def->type = ITEM_NODE; + unknown_def->name = "unknown"; + m_item_definitions.insert(std::make_pair("unknown", unknown_def)); - /* - Make a mesh from the node - */ - MeshMakeData mesh_make_data(gamedef, false); - u8 param2 = 0; - if (f.param_type_2 == CPT2_WALLMOUNTED) - param2 = 1; + ItemDefinition* air_def = new ItemDefinition; + air_def->type = ITEM_NODE; + air_def->name = "air"; + m_item_definitions.insert(std::make_pair("air", air_def)); - MapNode mesh_make_node(id, param1, param2); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - node_mesh = mapblock_mesh.getMesh(); - node_mesh->grab(); - video::SColor c(255, 255, 255, 255); - setMeshColor(node_mesh, c); - // scale and translate the mesh so it's a - // unit cube centered on the origin - scaleMesh(node_mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS)); - translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + ItemDefinition* ignore_def = new ItemDefinition; + ignore_def->type = ITEM_NODE; + ignore_def->name = "ignore"; + m_item_definitions.insert(std::make_pair("ignore", ignore_def)); } - /* - Draw node mesh into a render target texture - */ - if (need_rtt_mesh) { + virtual void registerItem(const ItemDefinition &def) + { + verbosestream<<"ItemDefManager: registering \""<inventory_texture = tsrc->generateTextureFromMesh(params); - // render-to-target didn't work - if (cc->inventory_texture == NULL) { + if(m_item_definitions.count(def.name) == 0) + m_item_definitions[def.name] = new ItemDefinition(def); + else + *(m_item_definitions[def.name]) = def; - cc->inventory_texture = tsrc->getTexture(f.tiledef[0].name); + // Remove conflicting alias if it exists + bool alias_removed = (m_aliases.erase(def.name) != 0); + if(alias_removed) + infostream<<"ItemDefManager: erased alias "< "<wield_mesh = node_mesh; - cc->wield_mesh->grab(); - // no way reference count can be smaller than 2 in this place! - assert(cc->wield_mesh->getReferenceCount() >= 2); + for (std::map::const_iterator + it = m_item_definitions.begin(); + it != m_item_definitions.end(); ++it) { + ItemDefinition *def = it->second; + // Serialize ItemDefinition and write wrapped in a string + std::ostringstream tmp_os(std::ios::binary); + def->serialize(tmp_os, protocol_version); + os << serializeString(tmp_os.str()); + } + + writeU16(os, m_aliases.size()); + + for (StringMap::const_iterator + it = m_aliases.begin(); + it != m_aliases.end(); ++it) { + os << serializeString(it->first); + os << serializeString(it->second); + } } - if (node_mesh) - node_mesh->drop(); -} -#endif + void deSerialize(std::istream &is) + { + // Clear everything + clear(); + // Deserialize + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported ItemDefManager version"); + u16 count = readU16(is); + for(u16 i=0; i + request = m_get_clientcached_queue.pop(); -/******************************************************************************/ + m_get_clientcached_queue.pushResult(request, + createClientCachedDirect(request.key, gamedef)); + } +#endif + } +private: + // Key is name + std::map m_item_definitions; + // Aliases + StringMap m_aliases; +#ifndef SERVER + // The id of the thread that is allowed to use irrlicht directly + threadid_t m_main_thread; + // A reference to this can be returned when nothing is found, to avoid NULLs + mutable ClientCached m_dummy_clientcached; + // Cached textures and meshes + mutable MutexedMap m_clientcached; + // Queued clientcached fetches (to be processed by the main thread) + mutable RequestQueue m_get_clientcached_queue; +#endif +}; IWritableItemDefManager* createItemDefManager() { diff --git a/src/itemdef.h b/src/itemdef.h index fb157705f..805b4aa5d 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -25,18 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#include #include "itemgroup.h" #include "sound.h" -#include "util/container.h" -#include "util/thread.h" - -#ifndef SERVER -#include "client/tile.h" -#endif - class IGameDef; -class INodeDefManager; struct ToolCapabilities; /* @@ -48,7 +39,7 @@ enum ItemType ITEM_NONE, ITEM_NODE, ITEM_CRAFT, - ITEM_TOOL + ITEM_TOOL, }; struct ItemDefinition @@ -166,77 +157,6 @@ public: virtual void processQueue(IGameDef *gamedef)=0; }; - -class CItemDefManager: public IWritableItemDefManager -{ -public: - CItemDefManager(); - virtual ~CItemDefManager(); - virtual const ItemDefinition& get(const std::string &name_) const; - virtual std::string getAlias(const std::string &name) const; - virtual std::set getAll() const; - virtual bool isKnown(const std::string &name_) const; - -#ifndef SERVER - // Get item inventory texture - virtual video::ITexture* getInventoryTexture(const std::string &name, - IGameDef *gamedef) const; - - // Get item wield mesh - virtual scene::IMesh* getWieldMesh(const std::string &name, - IGameDef *gamedef) const; -#endif - void clear(); - - virtual void registerItem(const ItemDefinition &def); - virtual void registerAlias(const std::string &name, - const std::string &convert_to); - void serialize(std::ostream &os, u16 protocol_version); - void deSerialize(std::istream &is); - - void processQueue(IGameDef *gamedef); - -private: - -#ifndef SERVER - struct ClientCached - { - video::ITexture *inventory_texture; - scene::IMesh *wield_mesh; - - ClientCached(); - }; - - void createNodeItemTexture(const std::string& name, - const ItemDefinition& def, INodeDefManager* nodedef, - ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const; - - ClientCached* createClientCachedDirect(const std::string &name, - IGameDef *gamedef) const; - - ClientCached* getClientCached(const std::string &name, - IGameDef *gamedef) const; - - // The id of the thread that is allowed to use irrlicht directly - threadid_t m_main_thread; - - // A reference to this can be returned when nothing is found, to avoid NULLs - mutable ClientCached m_dummy_clientcached; - - // Cached textures and meshes - mutable MutexedMap m_clientcached; - - // Queued clientcached fetches (to be processed by the main thread) - mutable RequestQueue m_get_clientcached_queue; -#endif - - // Key is name - std::map m_item_definitions; - - // Aliases - std::map m_aliases; -}; - IWritableItemDefManager* createItemDefManager(); #endif From 848b050a567e360e857577c50dee82494b14973b Mon Sep 17 00:00:00 2001 From: qiukeren Date: Mon, 21 Dec 2015 20:52:40 +0800 Subject: [PATCH 08/68] Add macos/freebsd missing endian.h include and add win endianness info --- src/util/serialize.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/util/serialize.h b/src/util/serialize.h index 58e59df22..36324a675 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -26,7 +26,17 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" #if HAVE_ENDIAN_H - #include + #ifdef _WIN32 + #define __BYTE_ORDER 0 + #define __LITTLE_ENDIAN 0 + #define __BIG_ENDIAN 1 + #elif defined(__MACH__) && defined(__APPLE__) + #include + #elif defined(__FreeBSD__) + #include + #else + #include + #endif #endif #include // for memcpy #include From c6bb6f99d1fc0acd0161307a17dd31eea4a56fff Mon Sep 17 00:00:00 2001 From: Rogier Date: Wed, 23 Dec 2015 11:38:50 +0100 Subject: [PATCH 09/68] Handle SQLITE_BUSY errors gracefully This allows other applications (e.g. minetestmapper) to interrogate the database while minetest is running, without causing an almost certain minetest crash. --- src/database-sqlite3.cpp | 60 ++++++++++++++++++++++++++++++++++++++++ src/database-sqlite3.h | 4 +++ 2 files changed, 64 insertions(+) diff --git a/src/database-sqlite3.cpp b/src/database-sqlite3.cpp index da3e2c86b..d2af042e6 100644 --- a/src/database-sqlite3.cpp +++ b/src/database-sqlite3.cpp @@ -31,10 +31,19 @@ SQLite format specification: #include "filesys.h" #include "exceptions.h" #include "settings.h" +#include "porting.h" #include "util/string.h" #include +// When to print messages when the database is being held locked by another process +// Note: I've seen occasional delays of over 250ms while running minetestmapper. +#define BUSY_INFO_TRESHOLD 100 // Print first informational message after 100ms. +#define BUSY_WARNING_TRESHOLD 250 // Print warning message after 250ms. Lag is increased. +#define BUSY_ERROR_TRESHOLD 1000 // Print error message after 1000ms. Significant lag. +#define BUSY_FATAL_TRESHOLD 3000 // Allow SQLITE_BUSY to be returned, which will cause a minetest crash. +#define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds + #define SQLRES(s, r) \ if ((s) != (r)) { \ @@ -56,6 +65,51 @@ SQLite format specification: sqlite3_errmsg(m_database)); \ } +int Database_SQLite3::busyHandler(void *data, int count) +{ + s64 &first_time = reinterpret_cast(data)[0]; + s64 &prev_time = reinterpret_cast(data)[1]; + s64 cur_time = getTimeMs(); + + if (count == 0) { + first_time = cur_time; + prev_time = first_time; + } else { + while (cur_time < prev_time) + cur_time += s64(1)<<32; + } + + if (cur_time - first_time < BUSY_INFO_TRESHOLD) { + ; // do nothing + } else if (cur_time - first_time >= BUSY_INFO_TRESHOLD && + prev_time - first_time < BUSY_INFO_TRESHOLD) { + infostream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms." << std::endl; + } else if (cur_time - first_time >= BUSY_WARNING_TRESHOLD && + prev_time - first_time < BUSY_WARNING_TRESHOLD) { + warningstream << "Sqlite3 database has been locked for " + << cur_time - first_time << " ms." << std::endl; + } else if (cur_time - first_time >= BUSY_ERROR_TRESHOLD && + prev_time - first_time < BUSY_ERROR_TRESHOLD) { + errorstream << "SQLite3 database has been locked for " + << cur_time - first_time << " ms; this causes lag." << std::endl; + } else if (cur_time - first_time >= BUSY_FATAL_TRESHOLD && + prev_time - first_time < BUSY_FATAL_TRESHOLD) { + errorstream << "Sqlite3 database has been locked for " + << cur_time - first_time << " ms - giving up!" << std::endl; + } else if ((cur_time - first_time) / BUSY_ERROR_INTERVAL != + (prev_time - first_time) / BUSY_ERROR_INTERVAL) { + // Safety net: keep reporting every BUSY_ERROR_INTERVAL + errorstream << "SQLite3 database has been locked for " + << (cur_time - first_time) / 1000 << " seconds!" << std::endl; + } + + prev_time = cur_time; + + // Make sqlite transaction fail if delay exceeds BUSY_FATAL_TRESHOLD + return cur_time - first_time < BUSY_FATAL_TRESHOLD; +} + Database_SQLite3::Database_SQLite3(const std::string &savedir) : m_initialized(false), @@ -107,6 +161,12 @@ void Database_SQLite3::openDatabase() throw FileNotGoodException("Cannot open database file"); } + if (sqlite3_busy_handler(m_database, sqlite3BusyHandler, busy_handler_data) != SQLITE_OK) { + errorstream << "SQLite3 database failed to set busy handler: " + << sqlite3_errmsg(m_database) << std::endl; + throw FileNotGoodException("Failed to set busy handler for sqlite connection"); + } + if (needs_create) { createDatabase(); } diff --git a/src/database-sqlite3.h b/src/database-sqlite3.h index a775742be..04a1825d9 100644 --- a/src/database-sqlite3.h +++ b/src/database-sqlite3.h @@ -63,6 +63,10 @@ private: sqlite3_stmt *m_stmt_delete; sqlite3_stmt *m_stmt_begin; sqlite3_stmt *m_stmt_end; + + s64 m_busy_handler_data[2]; + + static int busyHandler(void *data, int count); }; #endif From cb30facda0351a148005bfe33377c2ecc8f97af8 Mon Sep 17 00:00:00 2001 From: Rogier Date: Mon, 28 Dec 2015 19:34:16 +0100 Subject: [PATCH 10/68] Include custom error message in all SQLite3 exceptions. And replace manual tests for error with SQLOK() where possible. --- src/database-sqlite3.cpp | 65 +++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/database-sqlite3.cpp b/src/database-sqlite3.cpp index d2af042e6..56f937bf2 100644 --- a/src/database-sqlite3.cpp +++ b/src/database-sqlite3.cpp @@ -45,25 +45,19 @@ SQLite format specification: #define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds -#define SQLRES(s, r) \ +#define SQLRES(s, r, m) \ if ((s) != (r)) { \ - throw FileNotGoodException(std::string(\ - "SQLite3 database error (" \ - __FILE__ ":" TOSTRING(__LINE__) \ - "): ") +\ + throw FileNotGoodException(std::string(m) + ": " +\ sqlite3_errmsg(m_database)); \ } -#define SQLOK(s) SQLRES(s, SQLITE_OK) +#define SQLOK(s, m) SQLRES(s, SQLITE_OK, m) #define PREPARE_STATEMENT(name, query) \ - SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL)) + SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL),\ + "Failed to prepare query '" query "'") #define FINALIZE_STATEMENT(statement) \ - if (sqlite3_finalize(statement) != SQLITE_OK) { \ - throw FileNotGoodException(std::string( \ - "SQLite3: Failed to finalize " #statement ": ") + \ - sqlite3_errmsg(m_database)); \ - } + SQLOK(sqlite3_finalize(statement), "Failed to finalize " #statement) int Database_SQLite3::busyHandler(void *data, int count) { @@ -87,7 +81,7 @@ int Database_SQLite3::busyHandler(void *data, int count) << cur_time - first_time << " ms." << std::endl; } else if (cur_time - first_time >= BUSY_WARNING_TRESHOLD && prev_time - first_time < BUSY_WARNING_TRESHOLD) { - warningstream << "Sqlite3 database has been locked for " + warningstream << "SQLite3 database has been locked for " << cur_time - first_time << " ms." << std::endl; } else if (cur_time - first_time >= BUSY_ERROR_TRESHOLD && prev_time - first_time < BUSY_ERROR_TRESHOLD) { @@ -95,7 +89,7 @@ int Database_SQLite3::busyHandler(void *data, int count) << cur_time - first_time << " ms; this causes lag." << std::endl; } else if (cur_time - first_time >= BUSY_FATAL_TRESHOLD && prev_time - first_time < BUSY_FATAL_TRESHOLD) { - errorstream << "Sqlite3 database has been locked for " + errorstream << "SQLite3 database has been locked for " << cur_time - first_time << " ms - giving up!" << std::endl; } else if ((cur_time - first_time) / BUSY_ERROR_INTERVAL != (prev_time - first_time) / BUSY_ERROR_INTERVAL) { @@ -126,13 +120,15 @@ Database_SQLite3::Database_SQLite3(const std::string &savedir) : void Database_SQLite3::beginSave() { verifyDatabase(); - SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE); + SQLRES(sqlite3_step(m_stmt_begin), SQLITE_DONE, + "Failed to start SQLite3 transaction"); sqlite3_reset(m_stmt_begin); } void Database_SQLite3::endSave() { verifyDatabase(); - SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE); + SQLRES(sqlite3_step(m_stmt_end), SQLITE_DONE, + "Failed to commit SQLite3 transaction"); sqlite3_reset(m_stmt_end); } @@ -153,19 +149,12 @@ void Database_SQLite3::openDatabase() bool needs_create = !fs::PathExists(dbp); - 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; - throw FileNotGoodException("Cannot open database file"); - } + SQLOK(sqlite3_open_v2(dbp.c_str(), &m_database, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), + std::string("Failed to open SQLite3 database file ") + dbp); - if (sqlite3_busy_handler(m_database, sqlite3BusyHandler, busy_handler_data) != SQLITE_OK) { - errorstream << "SQLite3 database failed to set busy handler: " - << sqlite3_errmsg(m_database) << std::endl; - throw FileNotGoodException("Failed to set busy handler for sqlite connection"); - } + SQLOK(sqlite3_busy_handler(m_database, Database_SQLite3::busyHandler, + m_busy_handler_data), "Failed to set SQLite3 busy handler"); if (needs_create) { createDatabase(); @@ -173,7 +162,8 @@ void Database_SQLite3::openDatabase() std::string query_str = std::string("PRAGMA synchronous = ") + itos(g_settings->getU16("sqlite_synchronous")); - SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL)); + SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL), + "Failed to modify sqlite3 synchronous mode"); } void Database_SQLite3::verifyDatabase() @@ -200,7 +190,8 @@ void Database_SQLite3::verifyDatabase() inline void Database_SQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index) { - SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos))); + SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos)), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); } bool Database_SQLite3::deleteBlock(const v3s16 &pos) @@ -237,9 +228,10 @@ bool Database_SQLite3::saveBlock(const v3s16 &pos, const std::string &data) #endif bindPos(m_stmt_write, pos); - SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL)); + SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL), + "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__)); - SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE) + SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE, "Failed to save block") sqlite3_reset(m_stmt_write); return true; @@ -277,7 +269,8 @@ void Database_SQLite3::createDatabase() " `pos` INT PRIMARY KEY,\n" " `data` BLOB\n" ");\n", - NULL, NULL, NULL)); + NULL, NULL, NULL), + "Failed to create database table"); } void Database_SQLite3::listAllLoadableBlocks(std::vector &dst) @@ -299,10 +292,6 @@ Database_SQLite3::~Database_SQLite3() FINALIZE_STATEMENT(m_stmt_end) FINALIZE_STATEMENT(m_stmt_delete) - if (sqlite3_close(m_database) != SQLITE_OK) { - errorstream << "Database_SQLite3::~Database_SQLite3(): " - << "Failed to close database: " - << sqlite3_errmsg(m_database) << std::endl; - } + SQLOK(sqlite3_close(m_database), "Failed to close database"); } From 9719aded5430dd57591310c9cae06944dc345d42 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Fri, 18 Dec 2015 15:42:12 -0500 Subject: [PATCH 11/68] Fix cache path with RUN_IN_PLACE If an `XDG_CACHE_HOME` can't be found or `RUN_IN_PLACE` is enabled, `path_cache` is left at its default of `$PATH_USER/cache` (at a time when `PATH_USER` is `..`), rather than being reset to `$PATH_USER/cache` after `PATH_USER` has been properly set. --- src/porting.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/porting.cpp b/src/porting.cpp index 4a72e90fd..223299892 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -527,6 +527,7 @@ void initializePaths() path_share = execpath; path_user = execpath; } + path_cache = path_user + DIR_DELIM + "cache"; #else infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl; @@ -536,16 +537,16 @@ void initializePaths() // Initialize path_cache // First try $XDG_CACHE_HOME/PROJECT_NAME const char *cache_dir = getenv("XDG_CACHE_HOME"); + const char *home_dir = getenv("HOME"); if (cache_dir) { path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME; - } else { + } else if (home_dir) { // Then try $HOME/.cache/PROJECT_NAME - const char *home_dir = getenv("HOME"); - if (home_dir) { - path_cache = std::string(home_dir) + DIR_DELIM + ".cache" - + DIR_DELIM + PROJECT_NAME; - } - // If neither works, leave it at $PATH_USER/cache + path_cache = std::string(home_dir) + DIR_DELIM + ".cache" + + DIR_DELIM + PROJECT_NAME; + } else { + // If neither works, use $PATH_USER/cache + path_cache = path_user + DIR_DELIM + "cache"; } // Migrate cache folder to new location if possible migrateCachePath(); From a142e4f4b2256e7c4a16d14aecde6e04be33457c Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 30 Dec 2015 00:50:50 +0100 Subject: [PATCH 12/68] Fix client crashing when connecting to server My commit e2d54c9f9275e4f77ec33be8054621d42945f7a4 "shutdown when requested from lua in singleplayer too" broke minetest's feature to connect to servers. The client crashed after the connection init was complete. Thanks to @sofar for reporting the bug. Fixes #3498. --- src/game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.cpp b/src/game.cpp index 25424fa26..7ada1791e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1818,7 +1818,7 @@ void Game::run() while (device->run() && !(*kill || g_gamecallback->shutdown_requested - || server->getShutdownRequested())) { + || (server && server->getShutdownRequested()))) { /* Must be called immediately after a device->run() call because it * uses device->getTimer()->getTime() From 43c804a00b5f6177d0bb02404804234606197dc5 Mon Sep 17 00:00:00 2001 From: paramat Date: Tue, 29 Dec 2015 23:42:34 +0000 Subject: [PATCH 13/68] Minimal: Add mapgen alias for air --- games/minimal/mods/default/mapgen.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/games/minimal/mods/default/mapgen.lua b/games/minimal/mods/default/mapgen.lua index 65b67dae5..e13dcfaf4 100644 --- a/games/minimal/mods/default/mapgen.lua +++ b/games/minimal/mods/default/mapgen.lua @@ -3,6 +3,7 @@ -- +minetest.register_alias("mapgen_air", "air") minetest.register_alias("mapgen_stone", "default:stone") minetest.register_alias("mapgen_dirt", "default:dirt") minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass") From 64c060e1f2d94d8277246d8cdd8a886010564770 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 1 Jan 2016 18:14:30 +0200 Subject: [PATCH 14/68] filesys: safeWriteToFile(): Remove the target file before rename only on Windows Removing the target file on other platforms was enabled likely unintentionally by commit 5f1f1151d3a9c113902630adc16cc3f4845da7ba. This may be the reason why there has been corruption of files on Linux on hard shutdowns. Previously I described the problem and this fix in issue #3084. --- src/filesys.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/filesys.cpp b/src/filesys.cpp index 5fdc97634..501f9ad6c 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -693,13 +693,22 @@ bool safeWriteToFile(const std::string &path, const std::string &content) os.flush(); os.close(); if (os.fail()) { + // Remove the temporary file because writing it failed and it's useless. remove(tmp_file.c_str()); return false; } - // Copy file + // Move the finished temporary file over the real file +#ifdef _WIN32 + // On POSIX compliant systems rename() is specified to be able to swap the + // file in place of the destination file, making this a truly error-proof + // transaction. + // However, on Windows, the target file has to be removed first. remove(path.c_str()); +#endif if(rename(tmp_file.c_str(), path.c_str())) { + // Remove the temporary file because moving it over the target file + // failed. remove(tmp_file.c_str()); return false; } else { From a7c50a3080e55a6cf11175a60121696de7393dba Mon Sep 17 00:00:00 2001 From: Robert Zenz Date: Sat, 2 Jan 2016 22:14:09 +0100 Subject: [PATCH 15/68] Made it more clear that "[combine" does accept a list of files. --- doc/lua_api.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index b713b68bf..37d0aaabc 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -264,15 +264,15 @@ Example: default_cobble.png^[crack:10:1 -#### `[combine:x:,=:,=` +#### `[combine:x:,=:,=:...` * `` = width * `` = height -* ``/`` = x positions -* ``/`` = y positions -* ``/`` = textures to combine +* `` = x position +* `` = y position +* `` = texture to combine -Create a texture of size `` times `` and blit `` to (``,``) -and blit `` to (``,``). +Creates a texture of size `` times `` and blits the listed files to their +specified coordinates. Example: From 87dcee6ac2058bbf5264ea7f82874bba67277252 Mon Sep 17 00:00:00 2001 From: gregorycu Date: Sun, 3 Jan 2016 18:25:09 +1100 Subject: [PATCH 16/68] Prevent technically unsafe access with empty vector --- src/network/networkpacket.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index b5e451cdb..2b308f334 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -77,6 +77,9 @@ void NetworkPacket::putRawString(const char* src, u32 len) m_data.resize(m_datasize); } + if (m_datasize == 0) + return; + memcpy(&m_data[m_read_offset], src, len); m_read_offset += len; } From 09a6910dc78af7e403e3d68bed61199ecb5e0377 Mon Sep 17 00:00:00 2001 From: gregorycu Date: Sun, 3 Jan 2016 18:30:39 +1100 Subject: [PATCH 17/68] Add MinSizeRel and RelWithDebInfo to MSVCBuildDir check --- src/porting.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/porting.cpp b/src/porting.cpp index 223299892..fd1915b0d 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -163,6 +163,8 @@ bool detectMSVCBuildDir(const std::string &path) { const char *ends[] = { "bin\\Release", + "bin\\MinSizeRel", + "bin\\RelWithDebInfo", "bin\\Debug", "bin\\Build", NULL From e7e9171f37730c34dd687aa2b9ca5392aa41e46b Mon Sep 17 00:00:00 2001 From: gregorycu Date: Mon, 4 Jan 2016 16:15:50 +1100 Subject: [PATCH 18/68] Fix for commit 87dcee6 It uses the wrong variable and only covers some use cases. This change covers all use cases. --- src/network/networkpacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index 2b308f334..388afc18e 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -77,7 +77,7 @@ void NetworkPacket::putRawString(const char* src, u32 len) m_data.resize(m_datasize); } - if (m_datasize == 0) + if (len == 0) return; memcpy(&m_data[m_read_offset], src, len); From bd40ee2b95138139a8cfbef878b3461176688c15 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sun, 6 Dec 2015 21:34:30 -0500 Subject: [PATCH 19/68] Improve Doxyfile * Add main page. * Organize into sections. * Add threading sources. * Include SpatialAreaStore, LevelDB/Redis, sound, FreeType, and cURL in output. * Add logo. * Fix project name hardcoding. * Remove PAPER_TYPE (only used when GENERATE_LATEX is enabled). * Have dot render graphs as SVG (smaller, and works even if dot's text drawing functionality is broken). * Enable built-in STL support. * Enable search bar. * Switch from header-bar based navigation to treeview based navigation. * Enable dynamic HTML (collapses graphs). * Enable generation timestamp. --- doc/Doxyfile.in | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index d35fbf65f..3618b852d 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,34 +1,53 @@ -DOXYFILE_ENCODING = UTF-8 - -PROJECT_NAME = "Minetest" +# Project properties +PROJECT_NAME = @PROJECT_NAME_CAPITALIZED@ PROJECT_NUMBER = @VERSION_STRING@ +PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/misc/minetest.svg -STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src +# Parsing JAVADOC_AUTOBRIEF = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES SORT_MEMBERS_CTORS_1ST = YES WARN_IF_UNDOCUMENTED = NO +BUILTIN_STL_SUPPORT = YES +PREDEFINED = "USE_SPATIAL=1" \ + "USE_LEVELDB=1" \ + "USE_REDIS=1" \ + "USE_SOUND=1" \ + "USE_CURL=1" \ + "USE_FREETYPE=1" \ + "USE_GETTEXT=1" -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/ \ +# Input +RECURSIVE = NO +STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/doc/main_page.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/ \ @CMAKE_CURRENT_SOURCE_DIR@/src/client \ @CMAKE_CURRENT_SOURCE_DIR@/src/network \ @CMAKE_CURRENT_SOURCE_DIR@/src/util \ @CMAKE_CURRENT_SOURCE_DIR@/src/script \ @CMAKE_CURRENT_SOURCE_DIR@/src/script/common \ @CMAKE_CURRENT_SOURCE_DIR@/src/script/cpp_api \ - @CMAKE_CURRENT_SOURCE_DIR@/src/script/lua_api -RECURSIVE = NO - -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -GENERATE_LATEX = NO -PAPER_TYPE = a4wide + @CMAKE_CURRENT_SOURCE_DIR@/src/script/lua_api \ + @CMAKE_CURRENT_SOURCE_DIR@/src/threading +# Dot graphs HAVE_DOT = @DOXYGEN_DOT_FOUND@ CALL_GRAPH = YES CALLER_GRAPH = YES MAX_DOT_GRAPH_DEPTH = 3 DOT_MULTI_TARGETS = YES +DOT_IMAGE_FORMAT = svg + +# Output +GENERATE_LATEX = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +SEARCHENGINE = YES +DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES +HTML_DYNAMIC_SECTIONS = YES +HTML_TIMESTAMP = YES From 0bbbc6e13dc8180cf1d98f9866bc72a510162eb3 Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 30 Dec 2015 04:22:58 +0000 Subject: [PATCH 20/68] Liquids: Flow into and destroy 'floodable' nodes Add new node property 'floodable', default false Define "air" as floodable = true in C++ and lua --- builtin/game/item.lua | 1 + builtin/game/register.lua | 1 + doc/lua_api.txt | 1 + src/map.cpp | 70 ++++++++++++++++++--------------- src/nodedef.cpp | 4 ++ src/nodedef.h | 2 + src/script/common/c_content.cpp | 2 + 7 files changed, 49 insertions(+), 32 deletions(-) diff --git a/builtin/game/item.lua b/builtin/game/item.lua index d16601d30..c168bf096 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -574,6 +574,7 @@ core.nodedef_default = { diggable = true, climbable = false, buildable_to = false, + floodable = false, liquidtype = "none", liquid_alternative_flowing = "", liquid_alternative_source = "", diff --git a/builtin/game/register.lua b/builtin/game/register.lua index 992fdf744..ba5f69d67 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -289,6 +289,7 @@ core.register_node(":air", { pointable = false, diggable = false, buildable_to = true, + floodable = true, air_equivalent = true, drop = "", groups = {not_in_creative_inventory=1}, diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 37d0aaabc..ea5029e61 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3396,6 +3396,7 @@ Definition tables diggable = true, -- If false, can never be dug climbable = false, -- If true, can be climbed on (ladder) buildable_to = false, -- If true, placed nodes can replace this node + floodable = false, -- If true, liquids flow into and replace this node liquidtype = "none", -- "none"/"source"/"flowing" liquid_alternative_flowing = "", -- Flowing version of source liquid liquid_alternative_source = "", -- Source version of flowing liquid diff --git a/src/map.cpp b/src/map.cpp index ceebd40a3..ac29cfeee 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1654,10 +1654,10 @@ void Map::transformLiquids(std::map & modified_blocks) loop_max *= m_transforming_liquid_loop_count_multiplier; #endif - while(m_transforming_liquid.size() != 0) + while (m_transforming_liquid.size() != 0) { // This should be done here so that it is done when continue is used - if(loopcount >= initial_size || loopcount >= loop_max) + if (loopcount >= initial_size || loopcount >= loop_max) break; loopcount++; @@ -1674,21 +1674,24 @@ void Map::transformLiquids(std::map & modified_blocks) */ s8 liquid_level = -1; content_t liquid_kind = CONTENT_IGNORE; - LiquidType liquid_type = nodemgr->get(n0).liquid_type; + content_t floodable_node = CONTENT_AIR; + ContentFeatures cf = nodemgr->get(n0); + LiquidType liquid_type = cf.liquid_type; switch (liquid_type) { case LIQUID_SOURCE: liquid_level = LIQUID_LEVEL_SOURCE; - liquid_kind = nodemgr->getId(nodemgr->get(n0).liquid_alternative_flowing); + liquid_kind = nodemgr->getId(cf.liquid_alternative_flowing); break; case LIQUID_FLOWING: liquid_level = (n0.param2 & LIQUID_LEVEL_MASK); liquid_kind = n0.getContent(); break; case LIQUID_NONE: - // if this is an air node, it *could* be transformed into a liquid. otherwise, - // continue with the next node. - if (n0.getContent() != CONTENT_AIR) + // if this node is 'floodable', it *could* be transformed + // into a liquid, otherwise, continue with the next node. + if (!cf.floodable) continue; + floodable_node = n0.getContent(); liquid_kind = CONTENT_AIR; break; } @@ -1718,9 +1721,10 @@ void Map::transformLiquids(std::map & modified_blocks) } v3s16 npos = p0 + dirs[i]; NodeNeighbor nb(getNodeNoEx(npos), nt, npos); + ContentFeatures cfnb = nodemgr->get(nb.n); switch (nodemgr->get(nb.n.getContent()).liquid_type) { case LIQUID_NONE: - if (nb.n.getContent() == CONTENT_AIR) { + if (cfnb.floodable) { airs[num_airs++] = nb; // if the current node is a water source the neighbor // should be enqueded for transformation regardless of whether the @@ -1738,8 +1742,8 @@ void Map::transformLiquids(std::map & modified_blocks) case LIQUID_SOURCE: // if this node is not (yet) of a liquid type, choose the first liquid type we encounter if (liquid_kind == CONTENT_AIR) - liquid_kind = nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing); - if (nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing) != liquid_kind) { + liquid_kind = nodemgr->getId(cfnb.liquid_alternative_flowing); + if (nodemgr->getId(cfnb.liquid_alternative_flowing) != liquid_kind) { neutrals[num_neutrals++] = nb; } else { // Do not count bottom source, it will screw things up @@ -1750,8 +1754,8 @@ void Map::transformLiquids(std::map & modified_blocks) case LIQUID_FLOWING: // if this node is not (yet) of a liquid type, choose the first liquid type we encounter if (liquid_kind == CONTENT_AIR) - liquid_kind = nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing); - if (nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing) != liquid_kind) { + liquid_kind = nodemgr->getId(cfnb.liquid_alternative_flowing); + if (nodemgr->getId(cfnb.liquid_alternative_flowing) != liquid_kind) { neutrals[num_neutrals++] = nb; } else { flows[num_flows++] = nb; @@ -1770,8 +1774,8 @@ void Map::transformLiquids(std::map & modified_blocks) s8 max_node_level = -1; u8 range = nodemgr->get(liquid_kind).liquid_range; - if (range > LIQUID_LEVEL_MAX+1) - range = LIQUID_LEVEL_MAX+1; + if (range > LIQUID_LEVEL_MAX + 1) + range = LIQUID_LEVEL_MAX + 1; if ((num_sources >= 2 && nodemgr->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) { // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid) @@ -1780,10 +1784,11 @@ void Map::transformLiquids(std::map & modified_blocks) new_node_content = nodemgr->getId(nodemgr->get(liquid_kind).liquid_alternative_source); } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) { // liquid_kind is set properly, see above - new_node_content = liquid_kind; max_node_level = new_node_level = LIQUID_LEVEL_MAX; - if (new_node_level < (LIQUID_LEVEL_MAX+1-range)) - new_node_content = CONTENT_AIR; + if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) + new_node_content = liquid_kind; + else + new_node_content = floodable_node; } else { // no surrounding sources, so get the maximum level that can flow into this node for (u16 i = 0; i < num_flows; i++) { @@ -1794,16 +1799,16 @@ void Map::transformLiquids(std::map & modified_blocks) max_node_level = LIQUID_LEVEL_MAX; if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX) max_node_level = nb_liquid_level + WATER_DROP_BOOST; - } else if (nb_liquid_level > max_node_level) + } else if (nb_liquid_level > max_node_level) { max_node_level = nb_liquid_level; + } break; case NEIGHBOR_LOWER: break; case NEIGHBOR_SAME_LEVEL: if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK && - nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level) { + nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level) max_node_level = nb_liquid_level - 1; - } break; } } @@ -1821,23 +1826,25 @@ void Map::transformLiquids(std::map & modified_blocks) new_node_level = liquid_level + 1; if (new_node_level != max_node_level) must_reflow.push_back(p0); - } else + } else { new_node_level = max_node_level; + } - if (max_node_level >= (LIQUID_LEVEL_MAX+1-range)) + if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) new_node_content = liquid_kind; else - new_node_content = CONTENT_AIR; + new_node_content = floodable_node; } /* check if anything has changed. if not, just continue with the next node. */ - if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING || - ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level && - ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) - == flowing_down))) + if (new_node_content == n0.getContent() && + (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING || + ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level && + ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) + == flowing_down))) continue; @@ -1857,11 +1864,10 @@ void Map::transformLiquids(std::map & modified_blocks) // Find out whether there is a suspect for this action std::string suspect; - if(m_gamedef->rollback()) { + if (m_gamedef->rollback()) suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1); - } - if(m_gamedef->rollback() && !suspect.empty()){ + if (m_gamedef->rollback() && !suspect.empty()) { // Blame suspect RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true); // Get old node for rollback @@ -1880,10 +1886,10 @@ void Map::transformLiquids(std::map & modified_blocks) v3s16 blockpos = getNodeBlockPos(p0); MapBlock *block = getBlockNoCreateNoEx(blockpos); - if(block != NULL) { + if (block != NULL) { modified_blocks[blockpos] = block; // If new or old node emits light, MapBlock requires lighting update - if(nodemgr->get(n0).light_source != 0 || + if (nodemgr->get(n0).light_source != 0 || nodemgr->get(n00).light_source != 0) lighting_modified_blocks[block->getPos()] = block; } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index b5ccc3b94..2ebe1c131 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -233,6 +233,7 @@ void ContentFeatures::reset() diggable = true; climbable = false; buildable_to = false; + floodable = false; rightclickable = true; leveled = 0; liquid_type = LIQUID_NONE; @@ -318,6 +319,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const // the protocol version os< Date: Fri, 8 Jan 2016 15:37:11 +0100 Subject: [PATCH 21/68] Fix redis error reporting Previously, we assumed that reply->str was NULL terminated. However, this turned out to be not true, as users reported crashes in strlen connected to where reply->str was appended to an std::string. Use the method recomended by the docs, to read the length separately. --- src/database-redis.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/database-redis.cpp b/src/database-redis.cpp index 196d72f25..498e9d39a 100644 --- a/src/database-redis.cpp +++ b/src/database-redis.cpp @@ -92,7 +92,7 @@ bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data) if (reply->type == REDIS_REPLY_ERROR) { warningstream << "saveBlock: saving block " << PP(pos) - << " failed: " << reply->str << std::endl; + << " failed: " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); return false; } @@ -119,7 +119,7 @@ std::string Database_Redis::loadBlock(const v3s16 &pos) return str; } case REDIS_REPLY_ERROR: { - std::string errstr = reply->str; + std::string errstr(reply->str, reply->len); freeReplyObject(reply); errorstream << "loadBlock: loading block " << PP(pos) << " failed: " << errstr << std::endl; @@ -134,7 +134,7 @@ std::string Database_Redis::loadBlock(const v3s16 &pos) } errorstream << "loadBlock: loading block " << PP(pos) << " returned invalid reply type " << reply->type - << ": " << reply->str << std::endl; + << ": " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); throw FileNotGoodException(std::string( "Redis command 'HGET %s %s' gave invalid reply.")); @@ -151,7 +151,7 @@ bool Database_Redis::deleteBlock(const v3s16 &pos) "Redis command 'HDEL %s %s' failed: ") + ctx->errstr); } else if (reply->type == REDIS_REPLY_ERROR) { warningstream << "deleteBlock: deleting block " << PP(pos) - << " failed: " << reply->str << std::endl; + << " failed: " << std::string(reply->str, reply->len) << std::endl; freeReplyObject(reply); return false; } @@ -177,7 +177,8 @@ void Database_Redis::listAllLoadableBlocks(std::vector &dst) break; case REDIS_REPLY_ERROR: throw FileNotGoodException(std::string( - "Failed to get keys from database: ") + reply->str); + "Failed to get keys from database: ") + + std::string(reply->str, reply->len)); } freeReplyObject(reply); } From 95c1b66722bbad9e82ef14bcc53d31d035b49012 Mon Sep 17 00:00:00 2001 From: slemonide Date: Sat, 2 Jan 2016 03:21:17 -0800 Subject: [PATCH 22/68] Update lua_api.txt set_sky does work with on_joinplayer --- doc/lua_api.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ea5029e61..2ef25a9bd 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2636,8 +2636,6 @@ This is basically a reference to a C++ `ServerActiveObject` * `"regular"`: Uses 0 textures, `bgcolor` ignored * `"skybox"`: Uses 6 textures, `bgcolor` used * `"plain"`: Uses 0 textures, `bgcolor` used - * **Note**: currently does not work directly in `on_joinplayer`; use - `minetest.after(0)` in there. * `get_sky()`: returns bgcolor, type and a table with the textures * `override_day_night_ratio(ratio or nil)` * `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount From 386d190e0915a7ed270c313b4e9998f25d219e41 Mon Sep 17 00:00:00 2001 From: Robert Zenz Date: Thu, 7 Jan 2016 23:16:56 +0100 Subject: [PATCH 23/68] Clarified what get_node does. --- doc/lua_api.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2ef25a9bd..9088bd69d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1958,9 +1958,11 @@ and `minetest.auth_reload` call the authetification handler. * `minetest.remove_node(pos)` * Equivalent to `set_node(pos, "air")` * `minetest.get_node(pos)` - * Returns `{name="ignore", ...}` for unloaded area + * Returns the node at the given position as table in the format + `{name="node_name", param1=0, param2=0}`, returns `{name="ignore", param1=0, param2=0}` + for unloaded areas. * `minetest.get_node_or_nil(pos)` - * Returns `nil` for unloaded area + * Same as `get_node` but returns `nil` for unloaded areas. * `minetest.get_node_light(pos, timeofday)` * Gets the light value at the given position. Note that the light value "inside" the node at the given position is returned, so you usually want From 9c77725653061baa9ae169a966205a4eb2f6c3fd Mon Sep 17 00:00:00 2001 From: gregorycu Date: Mon, 4 Jan 2016 18:02:12 +1100 Subject: [PATCH 24/68] Replace instance of readsome with read in decompressZlib Make decompressZlib more robust --- src/serialization.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/serialization.cpp b/src/serialization.cpp index c0fbe10e2..79f66fcae 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -133,7 +133,8 @@ void decompressZlib(std::istream &is, std::ostream &os) if(z.avail_in == 0) { z.next_in = (Bytef*)input_buffer; - input_buffer_len = is.readsome(input_buffer, bufsize); + is.read(input_buffer, bufsize); + input_buffer_len = is.gcount(); z.avail_in = input_buffer_len; //dstream<<"read fail="<http://minetest.net/_media/screen2.png - http://minetest.net/_media/screenshot_4032289578.png + http://www.minetest.net/media/gallery/1.jpg + http://www.minetest.net/media/gallery/3.jpg + http://www.minetest.net/media/gallery/5.jpg http://minetest.net sfan5@live.de From fe3f6be4d262b466cd511595ad3b3c9bd5c89ea1 Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Fri, 13 Mar 2015 13:09:58 +0200 Subject: [PATCH 27/68] Simplify custom games packaging --- CMakeLists.txt | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea41d0d2f..f8278522e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,16 +149,9 @@ endif() install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client" DESTINATION "${SHAREDIR}") -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games") -set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game") -if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE}) - install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/") - install(FILES ${MINETEST_GAME_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/minetest_game/") - install(DIRECTORY ${MINETEST_GAME_SOURCE}/mods DESTINATION "${SHAREDIR}/games/minetest_game") - install(DIRECTORY ${MINETEST_GAME_SOURCE}/menu DESTINATION "${SHAREDIR}/games/minetest_game") -endif() +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games" DESTINATION "${SHAREDIR}" PATTERN ".git*" EXCLUDE) + if(BUILD_CLIENT) - #install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sounds/base/pack" DESTINATION "${SHAREDIR}/sounds/base") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base") endif() if(RUN_IN_PLACE) From 9943ae3f1a4fa1b687c780419b7f3a2d8091abe0 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 14 Dec 2015 19:01:32 -0200 Subject: [PATCH 28/68] New 3D Mode: Pageflip The pageflip mode requires a stereo quadbuffer, and a modern graphic card. Patch tested with NVidia 3D Vision. The mini-map is not drawn, but that's what is done for topbottom and sidebyside modes as well. Also most of the time the user would prefer the HUD to be off. That's for the user to decide though, and toggle it manually. Finally, the interocular distance (aka eye separation) is twice as much as the "3d_paralax_strength" settings. I find this a strange design decision. I didn't want to chance this though, since it's how the other 3d modes interpret this settings. --- builtin/settingtypes.txt | 3 +- minetest.conf.example | 3 +- src/client/clientlauncher.cpp | 4 ++ src/drawscene.cpp | 85 +++++++++++++++++++++++++++++++++++ src/game.cpp | 4 ++ 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 62f817062..6412ab4f6 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -454,7 +454,8 @@ fall_bobbing_amount (Fall bobbing) float 0.0 # - interlaced: odd/even line based polarisation screen support. # - topbottom: split screen top/bottom. # - sidebyside: split screen side by side. -3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside +# - pageflip: quadbuffer based 3d. +3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip # In-game chat console background color (R,G,B). console_color (Console color) string (0,0,0) diff --git a/minetest.conf.example b/minetest.conf.example index 40456f953..806ce62c2 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -518,7 +518,8 @@ # - interlaced: odd/even line based polarisation screen support. # - topbottom: split screen top/bottom. # - sidebyside: split screen side by side. -# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside +# - pageflip: quadbuffer based 3d. +# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, pageflip # 3d_mode = none # In-game chat console background color (R,G,B). diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index dfddef34e..be6426627 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -512,6 +512,9 @@ bool ClientLauncher::create_engine_device() u16 bits = g_settings->getU16("fullscreen_bpp"); u16 fsaa = g_settings->getU16("fsaa"); + // stereo buffer required for pageflip stereo + bool stereo_buffer = g_settings->get("3d_mode") == "pageflip"; + // Determine driver video::E_DRIVER_TYPE driverType = video::EDT_OPENGL; std::string driverstring = g_settings->get("video_driver"); @@ -537,6 +540,7 @@ bool ClientLauncher::create_engine_device() params.AntiAlias = fsaa; params.Fullscreen = fullscreen; params.Stencilbuffer = false; + params.Stereobuffer = stereo_buffer; params.Vsync = vsync; params.EventReceiver = receiver; params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); diff --git a/src/drawscene.cpp b/src/drawscene.cpp index 509f341d5..c716ca0d4 100644 --- a/src/drawscene.cpp +++ b/src/drawscene.cpp @@ -404,6 +404,84 @@ void draw_top_bottom_3d_mode(Camera& camera, bool show_hud, camera.getCameraNode()->setTarget(oldTarget); } +void draw_pageflip_3d_mode(Camera& camera, bool show_hud, + Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, + scene::ISceneManager* smgr, const v2u32& screensize, + bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv, + video::SColor skycolor) +{ + /* preserve old setup*/ + irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition(); + irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget(); + + irr::core::matrix4 startMatrix = + camera.getCameraNode()->getAbsoluteTransformation(); + irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget() + - camera.getCameraNode()->getAbsolutePosition()).setLength(1) + + camera.getCameraNode()->getAbsolutePosition(); + + //Left eye... + driver->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER); + + irr::core::vector3df leftEye; + irr::core::matrix4 leftMove; + leftMove.setTranslation( + irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"), + 0.0f, 0.0f)); + leftEye = (startMatrix * leftMove).getTranslation(); + + //clear the depth buffer, and color + driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255)); + camera.getCameraNode()->setPosition(leftEye); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + + if (show_hud) { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if (draw_wield_tool) + camera.drawWieldedTool(&leftMove); + + hud.drawHotbar(client.getPlayerItem()); + hud.drawLuaElements(camera.getOffset()); + } + + guienv->drawAll(); + + //Right eye... + driver->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER); + + irr::core::vector3df rightEye; + irr::core::matrix4 rightMove; + rightMove.setTranslation( + irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"), + 0.0f, 0.0f)); + rightEye = (startMatrix * rightMove).getTranslation(); + + //clear the depth buffer, and color + driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255)); + camera.getCameraNode()->setPosition(rightEye); + camera.getCameraNode()->setTarget(focusPoint); + smgr->drawAll(); + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + + if (show_hud) { + draw_selectionbox(driver, hud, hilightboxes, show_hud); + + if (draw_wield_tool) + camera.drawWieldedTool(&rightMove); + + hud.drawHotbar(client.getPlayerItem()); + hud.drawLuaElements(camera.getOffset()); + } + + guienv->drawAll(); + + camera.getCameraNode()->setPosition(oldPosition); + camera.getCameraNode()->setTarget(oldTarget); +} + void draw_plain(Camera& camera, bool show_hud, Hud& hud, std::vector hilightboxes, video::IVideoDriver* driver, bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv) @@ -466,6 +544,13 @@ void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr, smgr, screensize, draw_wield_tool, client, guienv, skycolor); show_hud = false; } + else if (draw_mode == "pageflip") + { + draw_pageflip_3d_mode(camera, show_hud, hud, hilightboxes, driver, + smgr, screensize, draw_wield_tool, client, guienv, skycolor); + draw_crosshair = false; + show_hud = false; + } else { draw_plain(camera, show_hud, hud, hilightboxes, driver, draw_wield_tool, client, guienv); diff --git a/src/game.cpp b/src/game.cpp index 7ada1791e..92d919931 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1872,6 +1872,10 @@ void Game::run() void Game::shutdown() { + if (g_settings->get("3d_mode") == "pageflip") { + driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS); + } + showOverlayMessage(wgettext("Shutting down..."), 0, 0, false); if (clouds) From 711808343db6d081e0aec550553a018554bed4d6 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 9 Jan 2016 15:11:43 -0500 Subject: [PATCH 29/68] Actually add Doxygen main page I apparently forgot to add this file in my previous commit (bd40ee2b95138139a8cfbef878b3461176688c15). --- doc/main_page.dox | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/main_page.dox diff --git a/doc/main_page.dox b/doc/main_page.dox new file mode 100644 index 000000000..8211d9cae --- /dev/null +++ b/doc/main_page.dox @@ -0,0 +1,8 @@ +/** @mainpage The Minetest engine internal documentation + +Welcome to the Minetest engine Doxygen documentation site!\n +This page documents the internal structure of the Minetest engine's C++ code.\n +Use the tree view at the left to navigate. + +*/ + From 106d4b7d05cfbba901abd540113991042d77bc97 Mon Sep 17 00:00:00 2001 From: ASL97 Date: Mon, 7 Dec 2015 17:39:48 +0800 Subject: [PATCH 30/68] Cache disable_anticheat and check it for "interacted_too_far" --- src/network/serverpackethandler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index a5aaf1ecb..7e348a94d 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1358,7 +1358,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) Check that target is reasonably close (only when digging or placing things) */ - if (action == 0 || action == 2 || action == 3) { + static const bool enable_anticheat = !g_settings->getBool("disable_anticheat"); + if ((action == 0 || action == 2 || action == 3) && + (enable_anticheat && !isSingleplayer())) { float d = player_pos.getDistanceFrom(pointed_pos_under); float max_d = BS * 14; // Just some large enough value if (d > max_d) { @@ -1495,7 +1497,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) /* Cheat prevention */ bool is_valid_dig = true; - if (!isSingleplayer() && !g_settings->getBool("disable_anticheat")) { + if (enable_anticheat && !isSingleplayer()) { v3s16 nocheat_p = playersao->getNoCheatDigPos(); float nocheat_t = playersao->getNoCheatDigTime(); playersao->noCheatDigEnd(); From 58babf8b1945f1a2db0180a4a3ed7b0d52872bef Mon Sep 17 00:00:00 2001 From: Rogier Date: Thu, 7 Jan 2016 12:33:26 +0100 Subject: [PATCH 31/68] Improve parsing of setting types from settingtypes.txt for settings tab - Accept numbers prefixed with '+' - Accept multiple spaces instead of just a single one where spaces are expected - Allow flags to have an empty default value --- builtin/mainmenu/tab_settings.lua | 36 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index db8d08d5e..f3a09a985 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -20,8 +20,8 @@ local FILENAME = "settingtypes.txt" local CHAR_CLASSES = { SPACE = "[%s]", VARIABLE = "[%w_%-%.]", - INTEGER = "[-]?[%d]", - FLOAT = "[-]?[%d%.]", + INTEGER = "[+-]?[%d]", + FLOAT = "[+-]?[%d%.]", FLAGS = "[%w_%-%.,]", } @@ -65,11 +65,11 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se -- so we can later strip it from the rest of the line .. "(" .. "([" .. CHAR_CLASSES.VARIABLE .. "+)" -- variable name - .. CHAR_CLASSES.SPACE + .. CHAR_CLASSES.SPACE .. "*" .. "%(([^%)]*)%)" -- readable name - .. CHAR_CLASSES.SPACE + .. CHAR_CLASSES.SPACE .. "*" .. "(" .. CHAR_CLASSES.VARIABLE .. "+)" -- type - .. CHAR_CLASSES.SPACE .. "?" + .. CHAR_CLASSES.SPACE .. "*" .. ")") if not first_part then @@ -88,8 +88,8 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se if setting_type == "int" then local default, min, max = remaining_line:match("^" -- first int is required, the last 2 are optional - .. "(" .. CHAR_CLASSES.INTEGER .. "+)" .. CHAR_CLASSES.SPACE .. "?" - .. "(" .. CHAR_CLASSES.INTEGER .. "*)" .. CHAR_CLASSES.SPACE .. "?" + .. "(" .. CHAR_CLASSES.INTEGER .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.INTEGER .. "*)" .. CHAR_CLASSES.SPACE .. "*" .. "(" .. CHAR_CLASSES.INTEGER .. "*)" .. "$") @@ -151,8 +151,8 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se if setting_type == "float" then local default, min, max = remaining_line:match("^" -- first float is required, the last 2 are optional - .. "(" .. CHAR_CLASSES.FLOAT .. "+)" .. CHAR_CLASSES.SPACE .. "?" - .. "(" .. CHAR_CLASSES.FLOAT .. "*)" .. CHAR_CLASSES.SPACE .. "?" + .. "(" .. CHAR_CLASSES.FLOAT .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLOAT .. "*)" .. CHAR_CLASSES.SPACE .. "*" .. "(" .. CHAR_CLASSES.FLOAT .. "*)" .."$") @@ -175,7 +175,11 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se end if setting_type == "enum" then - local default, values = remaining_line:match("^(.+)" .. CHAR_CLASSES.SPACE .. "(.+)$") + local default, values = remaining_line:match("^" + -- first value (default) may be empty (i.e. is optional) + .. "(" .. CHAR_CLASSES.VARIABLE .. "*)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLAGS .. "+)" + .. "$") if not default or values == "" then return "Invalid enum setting" @@ -211,14 +215,22 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se if setting_type == "flags" then local default, possible = remaining_line:match("^" - .. "(" .. CHAR_CLASSES.FLAGS .. "+)" .. CHAR_CLASSES.SPACE .. "" - .. "(" .. CHAR_CLASSES.FLAGS .. "+)" + -- first value (default) may be empty (i.e. is optional) + -- this is implemented by making the last value optional, and + -- swapping them around if it turns out empty. + .. "(" .. CHAR_CLASSES.FLAGS .. "+)" .. CHAR_CLASSES.SPACE .. "*" + .. "(" .. CHAR_CLASSES.FLAGS .. "*)" .. "$") if not default or not possible then return "Invalid flags setting" end + if possible == "" then + possible = default + default = "" + end + table.insert(settings, { name = name, readable_name = readable_name, From 31ac53dfd0eb0ab1e42921e85cf6575a16cbc38e Mon Sep 17 00:00:00 2001 From: Rogier Date: Thu, 7 Jan 2016 20:59:35 +0100 Subject: [PATCH 32/68] Fix the checking of flags values in the settings tab Changes: - Accept setting an empty flags-type value in the settings tab if the variable specification permits it - Don't accept substrings of flag values E.g. with values: 'one,two,three', 'hree', 'w', etc. used to be accepted. Not any more - Don't accept flags with random pattern-matching special characters E.g. with values: 'one,two,three', 'on.', '(o)[n]e*' etc. used to be accepted. Not any more. --- builtin/mainmenu/tab_settings.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index f3a09a985..472becea2 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -506,8 +506,8 @@ local function handle_change_setting_buttons(this, fields) local new_value = fields["te_setting_value"] for _,value in ipairs(new_value:split(",", true)) do value = value:trim() - if not value:match(CHAR_CLASSES.FLAGS .. "+") - or not setting.possible:match("[,]?" .. value .. "[,]?") then + local possible = "," .. setting.possible .. "," + if not possible:find("," .. value .. ",", 0, true) then this.data.error_message = fgettext_ne("\"$1\" is not a valid flag.", value) this.data.entered_text = fields["te_setting_value"] core.update_formspec(this:get_formspec()) From 3e0ea3c6eda27a7b6535570c2c208213be046494 Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 10 Jan 2016 03:27:32 +0000 Subject: [PATCH 33/68] Mgflat: Set blank default spflags. Unhide --- builtin/settingtypes.txt | 2 +- minetest.conf.example | 4 ++-- src/emerge.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 6412ab4f6..06d473808 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -936,7 +936,7 @@ mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (100, 100, # Occasional lakes and hills added to the flat world. # Flags that are not specified in the flag string are not modified from the default. # Flags starting with "no" are used to explicitly disable them. -mgflat_spflags (Mapgen flat flags) flags nolakes,nohills lakes,hills,nolakes,nohills +mgflat_spflags (Mapgen flat flags) flags lakes,hills,,nolakes,nohills # Y of flat ground. mgflat_ground_level (Mapgen flat ground level) int 8 diff --git a/minetest.conf.example b/minetest.conf.example index 806ce62c2..bea9b4ac3 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1187,8 +1187,8 @@ # Occasional lakes and hills added to the flat world. # Flags that are not specified in the flag string are not modified from the default. # Flags starting with "no" are used to explicitly disable them. -# type: flags possible values: lakes, hills, nolakes, nohills -# mgflat_spflags = nolakes,nohills +# type: flags possible values: lakes, hills, , nolakes, nohills +# mgflat_spflags = # Y of flat ground. # type: int diff --git a/src/emerge.cpp b/src/emerge.cpp index 6d4d84d7f..157be2e64 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -106,7 +106,7 @@ MapgenDesc g_reg_mapgens[] = { {"v5", new MapgenFactoryV5, true}, {"v6", new MapgenFactoryV6, true}, {"v7", new MapgenFactoryV7, true}, - {"flat", new MapgenFactoryFlat, false}, + {"flat", new MapgenFactoryFlat, true}, {"fractal", new MapgenFactoryFractal, true}, {"singlenode", new MapgenFactorySinglenode, false}, }; From 8fc8cb819b60dcaca887056e9fcb9cb7927412f1 Mon Sep 17 00:00:00 2001 From: paramat Date: Mon, 11 Jan 2016 00:30:03 +0000 Subject: [PATCH 34/68] Mapgen: Various fixes and improvements Lua_api.txt: Document 'minetest.registered_biomes' Minimal: Remove 'mapgen_air' alias Cavegen: Add fallback node for 'mapgen_ice' Dungeongen: Add fallback node for 'mapgen_river_water_source' Mgv5: Remove unnecessary '#include util/directiontables.h' Add missing 'this->'s in makeChunk() Mgv6: Edit empty line formatting Remove leading spaces in makeChunk() Add missing spaces after 'for' and 'if' Mgv7: Edit empty line formatting --- doc/lua_api.txt | 2 ++ games/minimal/mods/default/mapgen.lua | 1 - src/cavegen.cpp | 3 +++ src/dungeongen.cpp | 2 ++ src/mapgen_v5.cpp | 7 +++---- src/mapgen_v6.cpp | 20 +++++++++++--------- src/mapgen_v7.cpp | 1 + 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 0b3d5daa6..a3bb64818 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2461,6 +2461,8 @@ These functions return the leftover itemstack. * Map of Lua entities, indexed by active object id * `minetest.registered_ores` * List of registered ore definitions. +* `minetest.registered_biomes` + * List of registered biome definitions. * `minetest.registered_decorations` * List of registered decoration definitions. diff --git a/games/minimal/mods/default/mapgen.lua b/games/minimal/mods/default/mapgen.lua index e13dcfaf4..65b67dae5 100644 --- a/games/minimal/mods/default/mapgen.lua +++ b/games/minimal/mods/default/mapgen.lua @@ -3,7 +3,6 @@ -- -minetest.register_alias("mapgen_air", "air") minetest.register_alias("mapgen_stone", "default:stone") minetest.register_alias("mapgen_dirt", "default:dirt") minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass") diff --git a/src/cavegen.cpp b/src/cavegen.cpp index e1516af08..b8abfbca5 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -43,6 +43,9 @@ CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps) c_ice = ndef->getId("mapgen_ice"); this->np_caveliquids = &nparams_caveliquids; this->ystride = mg->csize.X; + + if (c_ice == CONTENT_IGNORE) + c_ice = CONTENT_AIR; dswitchint = ps->range(1, 14); flooded = ps->range(1, 2) == 2; diff --git a/src/dungeongen.cpp b/src/dungeongen.cpp index cb5ea97b6..ce92319e6 100644 --- a/src/dungeongen.cpp +++ b/src/dungeongen.cpp @@ -68,6 +68,8 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) // For mapgens using river water dp.c_river_water = mg->ndef->getId("mapgen_river_water_source"); + if (dp.c_river_water == CONTENT_IGNORE) + dp.c_river_water = mg->ndef->getId("mapgen_water_source"); } diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 92cf00202..48b717292 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -38,7 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mg_ore.h" #include "mg_decoration.h" #include "mapgen_v5.h" -#include "util/directiontables.h" FlagDesc flagdesc_mapgen_v5[] = { @@ -216,9 +215,9 @@ void MapgenV5::makeChunk(BlockMakeData *data) data->blockpos_requested.Y <= data->blockpos_max.Y && data->blockpos_requested.Z <= data->blockpos_max.Z); - generating = true; - vm = data->vmanip; - ndef = data->nodedef; + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; //TimeTaker t("makeChunk"); v3s16 blockpos_min = data->blockpos_min; diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 0a9f80dc9..57d0f59b3 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #include "mapgen.h" #include "voxel.h" #include "noise.h" @@ -37,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mg_decoration.h" #include "mapgen_v6.h" + FlagDesc flagdesc_mapgen_v6[] = { {"jungles", MGV6_JUNGLES}, {"biomeblend", MGV6_BIOMEBLEND}, @@ -47,7 +49,8 @@ FlagDesc flagdesc_mapgen_v6[] = { {NULL, 0} }; -/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) @@ -197,7 +200,6 @@ void MapgenV6Params::writeParams(Settings *settings) const //////////////////////// Some helper functions for the map generator - // Returns Y one under area minimum if not found s16 MapgenV6::find_stone_level(v2s16 p2d) { @@ -468,11 +470,11 @@ void MapgenV6::makeChunk(BlockMakeData *data) assert(data->vmanip); assert(data->nodedef); assert(data->blockpos_requested.X >= data->blockpos_min.X && - data->blockpos_requested.Y >= data->blockpos_min.Y && - data->blockpos_requested.Z >= data->blockpos_min.Z); + data->blockpos_requested.Y >= data->blockpos_min.Y && + data->blockpos_requested.Z >= data->blockpos_min.Z); assert(data->blockpos_requested.X <= data->blockpos_max.X && - data->blockpos_requested.Y <= data->blockpos_max.Y && - data->blockpos_requested.Z <= data->blockpos_max.Z); + data->blockpos_requested.Y <= data->blockpos_max.Y && + data->blockpos_requested.Z <= data->blockpos_max.Z); this->generating = true; this->vm = data->vmanip; @@ -808,7 +810,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) continue; // Drop mud on side - for(u32 di = 0; di < 4; di++) { + for (u32 di = 0; di < 4; di++) { v3s16 dirp = dirs4[di]; u32 i2 = i; // Move to side @@ -833,7 +835,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) vm->m_area.add_y(em, i2, -1); n2 = &vm->m_data[i2]; // if out of known area - if(vm->m_area.contains(i2) == false || + if (vm->m_area.contains(i2) == false || n2->getContent() == CONTENT_IGNORE) { dropped_to_unknown = true; break; @@ -848,7 +850,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) if (!dropped_to_unknown) { *n2 = *n; // Set old place to be air (or water) - if(old_is_water) + if (old_is_water) *n = MapNode(c_water_source); else *n = MapNode(CONTENT_AIR); diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 3842b1a96..50559f9a5 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -46,6 +46,7 @@ FlagDesc flagdesc_mapgen_v7[] = { {NULL, 0} }; + /////////////////////////////////////////////////////////////////////////////// From b4cbcaea262ba1b75e1b29b06d177e9d8d25b177 Mon Sep 17 00:00:00 2001 From: paramat Date: Mon, 11 Jan 2016 05:46:41 +0000 Subject: [PATCH 35/68] Mgv7/flat/fractal: Place biome top node on tunnel entrance floor --- src/mapgen_flat.cpp | 39 +++++++++++++++++++++++++++++---------- src/mapgen_fractal.cpp | 39 +++++++++++++++++++++++++++++---------- src/mapgen_v7.cpp | 41 ++++++++++++++++++++++++++++++----------- 3 files changed, 88 insertions(+), 31 deletions(-) diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index c961d755a..b7f01320f 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -551,20 +551,39 @@ void MapgenFlat::dustTopNodes() void MapgenFlat::generateCaves(s16 max_stone_y) { if (max_stone_y >= node_min.Y) { - u32 index = 0; + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + u32 index3d; for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - u32 vi = vm->m_area.index(node_min.X, y, z); - for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) { - float d1 = contour(noise_cave1->result[index]); - float d2 = contour(noise_cave2->result[index]); - if (d1 * d2 > 0.3f) { - content_t c = vm->m_data[vi].getContent(); - if (!ndef->get(c).is_ground_content || c == CONTENT_AIR) - continue; + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (open && (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + open = false; + } else { + open = false; } } } diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 6c03c4ca9..5c0d283ec 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -674,20 +674,39 @@ void MapgenFractal::dustTopNodes() void MapgenFractal::generateCaves(s16 max_stone_y) { if (max_stone_y >= node_min.Y) { - u32 index = 0; + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + u32 index3d; for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - u32 vi = vm->m_area.index(node_min.X, y, z); - for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) { - float d1 = contour(noise_cave1->result[index]); - float d2 = contour(noise_cave2->result[index]); - if (d1 * d2 > 0.3f) { - content_t c = vm->m_data[vi].getContent(); - if (!ndef->get(c).is_ground_content || c == CONTENT_AIR) - continue; + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (open && (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + open = false; + } else { + open = false; } } } diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 50559f9a5..1e4815486 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -863,20 +863,39 @@ void MapgenV7::addTopNodes() void MapgenV7::generateCaves(s16 max_stone_y) { if (max_stone_y >= node_min.Y) { - u32 index = 0; + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + u32 index3d; for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - u32 i = vm->m_area.index(node_min.X, y, z); - for (s16 x = node_min.X; x <= node_max.X; x++, i++, index++) { - float d1 = contour(noise_cave1->result[index]); - float d2 = contour(noise_cave2->result[index]); - if (d1 * d2 > 0.3f) { - content_t c = vm->m_data[i].getContent(); - if (!ndef->get(c).is_ground_content || c == CONTENT_AIR) - continue; + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + bool open = false; // Is column open to overground + u32 vi = vm->m_area.index(x, node_max.Y + 1, z); + index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + + (x - node_min.X); + // Biome of column + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]); - vm->m_data[i] = MapNode(CONTENT_AIR); + for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; + y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { + content_t c = vm->m_data[vi].getContent(); + if (c == CONTENT_AIR || c == biome->c_water_top || + c == biome->c_water) { + open = true; + continue; + } + // Ground + float d1 = contour(noise_cave1->result[index3d]); + float d2 = contour(noise_cave2->result[index3d]); + if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) { + // In tunnel and ground content, excavate + vm->m_data[vi] = MapNode(CONTENT_AIR); + } else if (open && (c == biome->c_filler || c == biome->c_stone)) { + // Tunnel entrance floor + vm->m_data[vi] = MapNode(biome->c_top); + open = false; + } else { + open = false; } } } From 3c6b2ffb10e053ad0b585347275034c4d889530d Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Wed, 13 Jan 2016 21:57:02 -0600 Subject: [PATCH 36/68] Add Valleys mapgen. --- build/android/jni/Android.mk | 1 + builtin/settingtypes.txt | 78 +++ minetest.conf.example | 41 ++ src/CMakeLists.txt | 1 + src/emerge.cpp | 2 + src/mapgen_valleys.cpp | 983 +++++++++++++++++++++++++++++++++++ src/mapgen_valleys.h | 194 +++++++ 7 files changed, 1300 insertions(+) create mode 100644 src/mapgen_valleys.cpp create mode 100644 src/mapgen_valleys.h diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 435dfa3b8..ff9d9ec43 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -179,6 +179,7 @@ LOCAL_SRC_FILES := \ jni/src/mapgen_v5.cpp \ jni/src/mapgen_v6.cpp \ jni/src/mapgen_v7.cpp \ + jni/src/mapgen_valleys.cpp \ jni/src/mapnode.cpp \ jni/src/mapsector.cpp \ jni/src/mesh.cpp \ diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 06d473808..833890a3e 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1033,6 +1033,84 @@ mgfractal_np_filler_depth (Mapgen fractal filler depth noise parameters) noise_p mgfractal_np_cave1 (Mapgen fractal cave1 noise parameters) noise_params 0, 12, (128, 128, 128), 52534, 4, 0.5, 2.0 mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0 +# Mapgen Valleys parameters +[***Mapgen Valleys] + +# General parameters +[****General] + +# Map generation attributes specific to Mapgen Valleys. +# Flags that are not specified in the flag string are not modified from the default. +# Flags starting with "no" are used to explicitly disable them. +# "altitude_chill" makes higher elevations colder, which may cause biome issues. +# "fast" produces softer terrain, more quickly +# "humid_rivers" modifies the humidity around rivers and in areas where water would tend to pool. It may interfere with delicately adjusted biomes. +# "rugged" and "cliffs" do nothing unless "fast" is enabled +mg_valleys_spflags (Valleys C Flags) flags altitude_chill,cliffs,humid_rivers,nofast,rugged altitude_chill,noaltitude_chill,cliffs,nocliffs,fast,nofast,humid_rivers,nohumid_rivers,rugged,norugged + +# The altitude at which temperature drops by 20C +mg_valleys_altitude_chill (Altitude Chill) int 90 + +# Average humidity +mg_valleys_humidity (Humidity) int 50 + +# The highest humidity around rivers in otherwise dry areas +mg_valleys_humidity_break_point (Humidity Break) int 65 + +# Maximum altitude where lava can emerge +mg_valleys_lava_max_height (Lava Height) int 0 + +# Maximum altitude where water occurs in caves (and tends to fall out) +mg_valleys_cave_water_max_height (Cave Water Height) int 31000 + +# How deep to make rivers +mg_valleys_river_depth (River Depth) int 4 + +# How wide to make rivers +mg_valleys_river_size (River Size) int 5 + +# Average temperature +mg_valleys_temperature (Temperature) int 50 + +# How often water occurs in caves (0-10) +mg_valleys_water_features (Water Features) int 3 + +# Noise parameters +[****Noises] + +# Cliff noise +mg_valleys_np_cliffs (Cliffs) noise_params 0, 1, (750, 750, 750), 8445, 5, 1.0, 2.0 + +# Mountain corrugation +mg_valleys_np_corr (Corrugation) noise_params 0, 1, (40, 40, 40), -3536, 4, 1.0, 2.0 + +# The depth of dirt or other filler +mg_valleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 + +# River noise -- rivers occur close to zero +mg_valleys_np_rivers (River Noise) noise_params 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 + +# Caves and tunnels form at the intersection of the two noises +mg_valleys_np_simple_caves_1 (Simple Caves #1) noise_params 0, 1, v3f(64, 64, 64), -8402, 3, 0.5, 2.0 + +# Caves and tunnels form at the intersection of the two noises +mg_valleys_np_simple_caves_2 (Simple Caves #2) noise_params 0, 1, v3f(64, 64, 64), 3944, 3, 0.5, 2.0 + +# Base terrain height +mg_valleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 + +# Raises terrain to make valleys around the rivers +mg_valleys_np_valley_depth (Valley Depth) noise_params 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 + +# Slope and fill work together to modify the heights +mg_valleys_np_inter_valley_fill (Valley Fill) noise_params 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 + +# Amplifies the valleys +mg_valleys_np_valley_profile (Valley Profile) noise_params 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 + +# Slope and fill work together to modify the heights +mg_valleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 + [*Security] # Prevent mods from doing insecure things like running shell commands. diff --git a/minetest.conf.example b/minetest.conf.example index bea9b4ac3..b95b32eea 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1313,6 +1313,47 @@ # type: noise_params # mgfractal_np_cave2 = 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0 +#### Mapgen Valleys + +#mg_valleys_spflags = altitude_chill,cliffs,humid_rivers,nofast,rugged +# "altitude_chill" makes higher elevations colder, which may cause biome issues. +# "fast" produces softer terrain, more quickly +# "humid_rivers" modifies the humidity around rivers and in areas where water would tend to pool. It may interfere with delicately adjusted biomes. +# "rugged" and "cliffs" do nothing unless "fast" is enabled +# +#mg_valleys_altitude_chill = 90 # the altitude at which temperature drops by 20C +#mg_valleys_cave_water_max_height = 31000 # max altitude of water in caves +#mg_valleys_humidity = 50 # the average humidity +#mg_valleys_humidity_break_point = 65 # The highest humidity around rivers in otherwise dry areas +#mg_valleys_lava_max_height = 0 # maximum altitude of lava +#mg_valleys_river_depth = 4 # how deep to make rivers +#mg_valleys_river_size = 5 # how wide to make rivers +#mg_valleys_temperature = 50 # the average temperature +#mg_valleys_water_features = 3 # how often water occurs in caves (0-10) +# +#mg_valleys_np_cliffs = 0, 1, (750, 750, 750), 8445, 5, 1.0, 2.0 +#mg_valleys_np_corr = 0, 1, (40, 40, 40), -3536, 4, 1.0, 2.0 +#mg_valleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0 +# +# River noise -- rivers occur close to zero +#mg_valleys_np_rivers = 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0 +# +#mg_valleys_np_simple_caves_1 = 0, 1, v3f(64, 64, 64), -8402, 3, 0.5, 2.0 +#mg_valleys_np_simple_caves_2 = 0, 1, v3f(64, 64, 64), 3944, 3, 0.5, 2.0 +# +# Base terrain height +#mg_valleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0 +# +# Raises terrain to make valleys around the rivers +#mg_valleys_np_valley_depth = 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0 +# +# Slope and fill work together to modify the heights +#mg_valleys_np_inter_valley_fill = 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0 +#mg_valleys_np_inter_valley_slope = 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0 +# +# Amplifies the valleys +#mg_valleys_np_valley_profile = 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0 + ## Security # Prevent mods from doing insecure things like running shell commands. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6256a8504..0b84ff85a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -388,6 +388,7 @@ set(common_SRCS mapgen_v5.cpp mapgen_v6.cpp mapgen_v7.cpp + mapgen_valleys.cpp mapnode.cpp mapsector.cpp mg_biome.cpp diff --git a/src/emerge.cpp b/src/emerge.cpp index 157be2e64..b188a7f41 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v5.h" #include "mapgen_v6.h" #include "mapgen_v7.h" +#include "mapgen_valleys.h" #include "mapgen_singlenode.h" #include "mg_biome.h" #include "mg_ore.h" @@ -108,6 +109,7 @@ MapgenDesc g_reg_mapgens[] = { {"v7", new MapgenFactoryV7, true}, {"flat", new MapgenFactoryFlat, true}, {"fractal", new MapgenFactoryFractal, true}, + {"valleys", new MapgenFactoryValleys, true}, {"singlenode", new MapgenFactorySinglenode, false}, }; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp new file mode 100644 index 000000000..c14ceb51e --- /dev/null +++ b/src/mapgen_valleys.cpp @@ -0,0 +1,983 @@ +/* +Minetest Valleys C +Copyright (C) 2010-2015 kwolekr, Ryan Kwolek +Copyright (C) 2010-2015 paramat, Matt Gregory +Copyright (C) 2016 Duane Robertson + +Based on Valleys Mapgen by Gael de Sailly + (https://forum.minetest.net/viewtopic.php?f=9&t=11430) +and mapgen_v7 by kwolekr and paramat. + +Licensing changed by permission of Gael de Sailly. + +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 "mapgen.h" +#include "voxel.h" +#include "noise.h" +#include "mapblock.h" +#include "mapnode.h" +#include "map.h" +#include "content_sao.h" +#include "nodedef.h" +#include "voxelalgorithms.h" +#include "settings.h" // For g_settings +#include "emerge.h" +#include "dungeongen.h" +#include "treegen.h" +#include "mg_biome.h" +#include "mg_ore.h" +#include "mg_decoration.h" +#include "mapgen_valleys.h" + +//#undef NDEBUG +//#include "assert.h" + +//#include "util/timetaker.h" +//#include "profiler.h" + + +//static Profiler mapgen_prof; +//Profiler *mapgen_profiler = &mapgen_prof; + +static FlagDesc flagdesc_mapgen_valleys[] = { + {"altitude_chill", MG_VALLEYS_ALT_CHILL}, + {"cliffs", MG_VALLEYS_CLIFFS}, + {"fast", MG_VALLEYS_FAST}, + {"humid_rivers", MG_VALLEYS_HUMID_RIVERS}, + {"rugged", MG_VALLEYS_RUGGED}, + {NULL, 0} +}; + +/////////////////////////////////////////////////////////////////////////////// + + +MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge) + : Mapgen(mapgenid, params, emerge) +{ + this->m_emerge = emerge; + this->bmgr = emerge->biomemgr; + + //// amount of elements to skip for the next index + //// for noise/height/biome maps (not vmanip) + this->ystride = csize.X; + this->zstride = csize.X * (csize.Y + 2); + + this->biomemap = new u8[csize.X * csize.Z]; + this->heightmap = new s16[csize.X * csize.Z]; + this->heatmap = NULL; + this->humidmap = NULL; + + MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams; + this->spflags = sp->spflags; + + this->cliff_terrain = (spflags & MG_VALLEYS_CLIFFS); + this->fast_terrain = (spflags & MG_VALLEYS_FAST); + this->humid_rivers = (spflags & MG_VALLEYS_HUMID_RIVERS); + this->rugged_terrain = (spflags & MG_VALLEYS_RUGGED); + this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL); + + this->altitude_chill = sp->altitude_chill; + this->cave_water_max_height = sp->cave_water_max_height; + this->humidity_adjust = sp->humidity - 50.f; + this->humidity_break_point = sp->humidity_break_point; + this->lava_max_height = sp->lava_max_height; + this->river_depth = sp->river_depth + 1.f; + this->river_size = sp->river_size / 100.f; + this->temperature_adjust = sp->temperature - 50.f; + this->water_features = MYMAX(1, MYMIN(11, 11 - sp->water_features)); + + //// 2D Terrain noise + noise_cliffs = new Noise(&sp->np_cliffs, seed, csize.X, csize.Z); + noise_corr = new Noise(&sp->np_corr, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); + noise_inter_valley_slope = new Noise(&sp->np_inter_valley_slope, seed, csize.X, csize.Z); + noise_rivers = new Noise(&sp->np_rivers, seed, csize.X, csize.Z); + noise_terrain_height = new Noise(&sp->np_terrain_height, seed, csize.X, csize.Z); + noise_valley_depth = new Noise(&sp->np_valley_depth, seed, csize.X, csize.Z); + noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z); + + if (this->fast_terrain) + noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Z); + + //// 3D Terrain noise + noise_simple_caves_1 = new Noise(&sp->np_simple_caves_1, seed, csize.X, csize.Y + 2, csize.Z); + noise_simple_caves_2 = new Noise(&sp->np_simple_caves_2, seed, csize.X, csize.Y + 2, csize.Z); + + if (!this->fast_terrain) + noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); + + //// Biome noise + noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z); + noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z); + noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z); + noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z); + + //// Resolve nodes to be used + INodeDefManager *ndef = emerge->ndef; + + c_cobble = ndef->getId("mapgen_cobble"); + c_desert_stone = ndef->getId("mapgen_desert_stone"); + c_dirt = ndef->getId("mapgen_dirt"); + c_lava_source = ndef->getId("mapgen_lava_source"); + c_mossycobble = ndef->getId("mapgen_mossycobble"); + c_river_water_source = ndef->getId("mapgen_river_water_source"); + c_sand = ndef->getId("mapgen_sand"); + c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); + c_sandstone = ndef->getId("mapgen_sandstone"); + c_stair_cobble = ndef->getId("mapgen_stair_cobble"); + c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); + c_stone = ndef->getId("mapgen_stone"); + c_water_source = ndef->getId("mapgen_water_source"); + + if (c_mossycobble == CONTENT_IGNORE) + c_mossycobble = c_cobble; + if (c_river_water_source == CONTENT_IGNORE) + c_river_water_source = c_water_source; + if (c_sand == CONTENT_IGNORE) + c_sand = c_stone; + if (c_sandstonebrick == CONTENT_IGNORE) + c_sandstonebrick = c_sandstone; + if (c_stair_cobble == CONTENT_IGNORE) + c_stair_cobble = c_cobble; + if (c_stair_sandstonebrick == CONTENT_IGNORE) + c_stair_sandstonebrick = c_sandstone; +} + + +MapgenValleys::~MapgenValleys() +{ + delete noise_cliffs; + delete noise_corr; + delete noise_filler_depth; + delete noise_heat; + delete noise_heat_blend; + delete noise_humidity; + delete noise_humidity_blend; + delete noise_inter_valley_fill; + delete noise_inter_valley_slope; + delete noise_rivers; + delete noise_simple_caves_1; + delete noise_simple_caves_2; + delete noise_terrain_height; + delete noise_valley_depth; + delete noise_valley_profile; + + delete[] heightmap; + delete[] biomemap; +} + + +MapgenValleysParams::MapgenValleysParams() +{ + spflags = MG_VALLEYS_CLIFFS | MG_VALLEYS_RUGGED + | MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL; + + altitude_chill = 90; // The altitude at which temperature drops by 20C. + // Water in caves will never be higher than this. + cave_water_max_height = MAX_MAP_GENERATION_LIMIT; + humidity = 50; + // the maximum humidity around rivers in otherwise dry areas + humidity_break_point = 65; + lava_max_height = 0; // Lava will never be higher than this. + river_depth = 4; // How deep to carve river channels. + river_size = 5; // How wide to make rivers. + temperature = 50; + water_features = 3; // How often water will occur in caves. + + np_cliffs = NoiseParams(0.f, 1.f, v3f(750, 750, 750), 8445, 5, 1.f, 2.f); + np_corr = NoiseParams(0.f, 1.f, v3f(40, 40, 40), -3536, 4, 1.f, 2.f); + np_filler_depth = NoiseParams(0.f, 1.2f, v3f(256, 256, 256), 1605, 3, 0.5f, 2.f); + np_inter_valley_fill = NoiseParams(0.f, 1.f, v3f(256, 512, 256), 1993, 6, 0.8f, 2.f); + np_inter_valley_slope = NoiseParams(0.5f, 0.5f, v3f(128, 128, 128), 746, 1, 1.f, 2.f); + np_rivers = NoiseParams(0.f, 1.f, v3f(256, 256, 256), -6050, 5, 0.6f, 2.f); + np_simple_caves_1 = NoiseParams(0.f, 1.f, v3f(64, 64, 64), -8402, 3, 0.5f, 2.f); + np_simple_caves_2 = NoiseParams(0.f, 1.f, v3f(64, 64, 64), 3944, 3, 0.5f, 2.f); + np_terrain_height = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f); + np_valley_depth = NoiseParams(5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f); + np_valley_profile = NoiseParams(0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f); + } + + +void MapgenValleysParams::readParams(const Settings *settings) +{ + settings->getFlagStrNoEx("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys); + + settings->getU16NoEx("mg_valleys_altitude_chill", altitude_chill); + settings->getS16NoEx("mg_valleys_cave_water_max_height", cave_water_max_height); + settings->getS16NoEx("mg_valleys_humidity", humidity); + settings->getS16NoEx("mg_valleys_humidity_break_point", humidity_break_point); + settings->getS16NoEx("mg_valleys_lava_max_height", lava_max_height); + settings->getU16NoEx("mg_valleys_river_depth", river_depth); + settings->getU16NoEx("mg_valleys_river_size", river_size); + settings->getS16NoEx("mg_valleys_temperature", temperature); + settings->getU16NoEx("mg_valleys_water_features", water_features); + + settings->getNoiseParams("mg_valleys_np_cliffs", np_cliffs); + settings->getNoiseParams("mg_valleys_np_corr", np_corr); + settings->getNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); + settings->getNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); + settings->getNoiseParams("mg_valleys_np_rivers", np_rivers); + settings->getNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); + settings->getNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2); + settings->getNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); + settings->getNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); + settings->getNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); +} + + +void MapgenValleysParams::writeParams(Settings *settings) const +{ + settings->setFlagStr("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX); + + settings->setU16("mg_valleys_altitude_chill", altitude_chill); + settings->setS16("mg_valleys_cave_water_max_height", cave_water_max_height); + settings->setS16("mg_valleys_humidity", humidity); + settings->setS16("mg_valleys_humidity_break_point", humidity_break_point); + settings->setS16("mg_valleys_lava_max_height", lava_max_height); + settings->setU16("mg_valleys_river_depth", river_depth); + settings->setU16("mg_valleys_river_size", river_size); + settings->setS16("mg_valleys_temperature", temperature); + settings->setU16("mg_valleys_water_features", water_features); + + settings->setNoiseParams("mg_valleys_np_cliffs", np_cliffs); + settings->setNoiseParams("mg_valleys_np_corr", np_corr); + settings->setNoiseParams("mg_valleys_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mg_valleys_np_inter_valley_fill", np_inter_valley_fill); + settings->setNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope); + settings->setNoiseParams("mg_valleys_np_rivers", np_rivers); + settings->setNoiseParams("mg_valleys_np_simple_caves_1", np_simple_caves_1); + settings->setNoiseParams("mg_valleys_np_simple_caves_2", np_simple_caves_2); + settings->setNoiseParams("mg_valleys_np_terrain_height", np_terrain_height); + settings->setNoiseParams("mg_valleys_np_valley_depth", np_valley_depth); + settings->setNoiseParams("mg_valleys_np_valley_profile", np_valley_profile); +} + + +/////////////////////////////////////// + + +void MapgenValleys::makeChunk(BlockMakeData *data) +{ + // Pre-conditions + assert(data->vmanip); + assert(data->nodedef); + assert(data->blockpos_requested.X >= data->blockpos_min.X && + data->blockpos_requested.Y >= data->blockpos_min.Y && + data->blockpos_requested.Z >= data->blockpos_min.Z); + assert(data->blockpos_requested.X <= data->blockpos_max.X && + data->blockpos_requested.Y <= data->blockpos_max.Y && + data->blockpos_requested.Z <= data->blockpos_max.Z); + + this->generating = true; + this->vm = data->vmanip; + this->ndef = data->nodedef; + + //TimeTaker t("makeChunk"); + + v3s16 blockpos_min = data->blockpos_min; + v3s16 blockpos_max = data->blockpos_max; + node_min = blockpos_min * MAP_BLOCKSIZE; + node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; + full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); + + blockseed = getBlockSeed2(full_node_min, seed); + + // Generate noise maps and base terrain height. + calculateNoise(); + + // Generate base terrain with initial heightmaps + s16 stone_surface_max_y = generateTerrain(); + + // Create biomemap at heightmap surface + bmgr->calcBiomes(csize.X, csize.Z, heatmap, humidmap, heightmap, biomemap); + + // Actually place the biome-specific nodes + MgStoneType stone_type = generateBiomes(heatmap, humidmap); + + // Cave creation. + if (flags & MG_CAVES) + generateSimpleCaves(stone_surface_max_y); + + // Dungeon creation + if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) { + DungeonParams dp; + + dp.np_rarity = nparams_dungeon_rarity; + dp.np_density = nparams_dungeon_density; + dp.np_wetness = nparams_dungeon_wetness; + dp.c_water = c_water_source; + if (stone_type == STONE) { + dp.c_cobble = c_cobble; + dp.c_moss = c_mossycobble; + dp.c_stair = c_stair_cobble; + + dp.diagonal_dirs = false; + dp.mossratio = 3.f; + dp.holesize = v3s16(1, 2, 1); + dp.roomsize = v3s16(0, 0, 0); + dp.notifytype = GENNOTIFY_DUNGEON; + } else if (stone_type == DESERT_STONE) { + dp.c_cobble = c_desert_stone; + dp.c_moss = c_desert_stone; + dp.c_stair = c_desert_stone; + + dp.diagonal_dirs = true; + dp.mossratio = 0.f; + dp.holesize = v3s16(2, 3, 2); + dp.roomsize = v3s16(2, 5, 2); + dp.notifytype = GENNOTIFY_TEMPLE; + } else if (stone_type == SANDSTONE) { + dp.c_cobble = c_sandstonebrick; + dp.c_moss = c_sandstonebrick; + dp.c_stair = c_sandstonebrick; + + dp.diagonal_dirs = false; + dp.mossratio = 0.f; + dp.holesize = v3s16(2, 2, 2); + dp.roomsize = v3s16(2, 0, 2); + dp.notifytype = GENNOTIFY_DUNGEON; + } + + DungeonGen dgen(this, &dp); + dgen.generate(blockseed, full_node_min, full_node_max); + } + + // Generate the registered decorations + if (flags & MG_DECORATIONS) + m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); + + // Generate the registered ores + m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); + + // Sprinkle some dust on top after everything else was generated + dustTopNodes(); + + //TimeTaker tll("liquid_lighting"); + + updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + + if (flags & MG_LIGHT) + calcLighting( + node_min - v3s16(0, 1, 0), + node_max + v3s16(0, 1, 0), + full_node_min, + full_node_max); + + //mapgen_profiler->avg("liquid_lighting", tll.stop() / 1000.f); + //mapgen_profiler->avg("makeChunk", t.stop() / 1000.f); + + this->generating = false; +} + + +// Populate the noise tables and do most of the +// calculation necessary to determine terrain height. +void MapgenValleys::calculateNoise() +{ + //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); + + int x = node_min.X; + int y = node_min.Y - 1; + int z = node_min.Z; + + //TimeTaker tcn("actualNoise"); + + noise_filler_depth->perlinMap2D(x, z); + noise_heat_blend->perlinMap2D(x, z); + noise_heat->perlinMap2D(x, z); + noise_humidity_blend->perlinMap2D(x, z); + noise_humidity->perlinMap2D(x, z); + noise_inter_valley_slope->perlinMap2D(x, z); + noise_rivers->perlinMap2D(x, z); + noise_terrain_height->perlinMap2D(x, z); + noise_valley_depth->perlinMap2D(x, z); + noise_valley_profile->perlinMap2D(x, z); + + if (fast_terrain) { + // Make this 2D for speed, if requested. + noise_inter_valley_fill->perlinMap2D(x, z); + + if (cliff_terrain) + noise_cliffs->perlinMap2D(x, z); + if (rugged_terrain) + noise_corr->perlinMap2D(x, z); + } else { + noise_inter_valley_fill->perlinMap3D(x, y, z); + } + + if (flags & MG_CAVES) { + noise_simple_caves_1->perlinMap3D(x, y, z); + noise_simple_caves_2->perlinMap3D(x, y, z); + } + + //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f); + + for (s32 index = 0; index < csize.X * csize.Z; index++) { + noise_heat->result[index] += noise_heat_blend->result[index]; + noise_heat->result[index] += temperature_adjust; + noise_humidity->result[index] += noise_humidity_blend->result[index]; + } + + TerrainNoise tn; + + u32 index = 0; + for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++) + for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) { + // The parameters that we actually need to generate terrain + // are passed by address (and the return value). + tn.terrain_height = noise_terrain_height->result[index]; + // River noise is replaced with base terrain, which + // is basically the height of the water table. + tn.rivers = &noise_rivers->result[index]; + // Valley depth noise is replaced with the valley + // number that represents the height of terrain + // over rivers and is used to determine about + // how close a river is for humidity calculation. + tn.valley = &noise_valley_depth->result[index]; + tn.valley_profile = noise_valley_profile->result[index]; + // Slope noise is replaced by the calculated slope + // which is used to get terrain height in the slow + // method, to create sharper mountains. + tn.slope = &noise_inter_valley_slope->result[index]; + tn.inter_valley_fill = noise_inter_valley_fill->result[index]; + tn.cliffs = noise_cliffs->result[index]; + tn.corr = noise_corr->result[index]; + + // This is the actual terrain height. + float mount = terrainLevelFromNoise(&tn); + noise_terrain_height->result[index] = mount; + + if (fast_terrain) { + // Assign humidity adjusted by water proximity. + // I can't think of a reason why a mod would expect base humidity + // from noise or at any altitude other than ground level. + noise_humidity->result[index] = humidityByTerrain( + noise_humidity->result[index], + mount, + noise_rivers->result[index], + noise_valley_depth->result[index]); + + // Assign heat adjusted by altitude. See humidity, above. + if (use_altitude_chill && mount > 0.f) + noise_heat->result[index] *= pow(0.5f, (mount - altitude_chill / 3.f) / altitude_chill); + } + } + + heatmap = noise_heat->result; + humidmap = noise_humidity->result; +} + + +// This keeps us from having to maintain two similar sets of +// complicated code to determine ground level. +float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) +{ + float inter_valley_slope = *tn->slope; + + // The square function changes the behaviour of this noise: + // very often small, and sometimes very high. + float valley_d = pow(*tn->valley, 2); + + // valley_d is here because terrain is generally higher where valleys + // are deep (mountains). base represents the height of the + // rivers, most of the surface is above. + float base = tn->terrain_height + valley_d; + + // "river" represents the distance from the river, in arbitrary units. + float river = fabs(*tn->rivers) - river_size; + + // Use the curve of the function 1−exp(−(x/a)²) to model valleys. + // Making "a" vary (0 < a ≤ 1) changes the shape of the valleys. + // Try it with a geometry software ! + // (here x = "river" and a = valley_profile). + // "valley" represents the height of the terrain, from the rivers. + *tn->valley = valley_d * (1.f - exp(- pow(river / tn->valley_profile, 2))); + + // approximate height of the terrain at this point + float mount = base + *tn->valley; + + *tn->slope *= *tn->valley; + + // Rivers are placed where "river" is negative, so where the original + // noise value is close to zero. + // Base ground is returned as rivers since it's basically the water table. + *tn->rivers = base; + if (river < 0.f) { + // Use the the function −sqrt(1−x²) which models a circle. + float depth = (river_depth * sqrt(1.f - pow((river / river_size + 1), 2))); + + // base - depth : height of the bottom of the river + // water_level - 2 : don't make rivers below 2 nodes under the surface + u16 min_bottom = 2; + if (!fast_terrain) + min_bottom = 6; + mount = fmin(fmax(base - depth, (float) (water_level - min_bottom)), mount); + + // Slope has no influence on rivers. + *tn->slope = 0.f; + } + + if (fast_terrain) { + // The penultimate step builds up the heights, but we reduce it + // occasionally to create cliffs. + float delta = sin(tn->inter_valley_fill) * *tn->slope; + if (cliff_terrain && tn->cliffs >= 0.2f) + mount += delta * 0.66f; + else + mount += delta; + + // Use yet another noise to make the heights look more rugged. + if (rugged_terrain + && mount > water_level + && fabs(inter_valley_slope * tn->inter_valley_fill) < 0.3f) + mount += ((delta < 0.f) ? -1.f : 1.f) * pow(fabs(delta), 0.5f) * fabs(sin(tn->corr)); + } + + return mount; +} + + +// This avoids duplicating the code in terrainLevelFromNoise, adding +// only the final step of terrain generation without a noise map. +float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) +{ + float mount = terrainLevelFromNoise(tn); + + if (!fast_terrain) { + for (s16 y = round(mount); y <= round(mount) + 1000; y++) { + float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed); + + if (fill * *tn->slope <= y - mount) { + mount = fmax(y - 1, mount); + break; + } + } + } + + return mount; +} + + +float MapgenValleys::humidityByTerrain( + float humidity_base, + float mount, + float rivers, + float valley) +{ + // Although the original valleys adjusts humidity by distance + // from seawater, this causes problems with the default biomes. + // Adjust only by freshwater proximity. + float humidity = humidity_base + humidity_adjust; + + if (humid_rivers && mount > water_level) { + // Offset to make everything average the same. + humidity -= (humidity_break_point - humidity_adjust) / 3.f; + + // This method is from the original lua. + float water_table = pow(0.5f, fmax(rivers / 3.f, 0.f)); + // This adds humidity next to rivers and lakes. + float river_water = pow(0.5f, fmax(valley / 12.f, 0.f)); + // Combine the two. + float water = water_table + (1.f - water_table) * river_water; + humidity = fmax(humidity, (humidity_break_point * water)); + } + + return humidity; +} + + +inline int MapgenValleys::getGroundLevelAtPoint(v2s16 p) +{ + // Base terrain calculation + return terrainLevelAtPoint(p.X, p.Y); +} + + +float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z) +{ + TerrainNoise tn; + + float rivers = NoisePerlin2D(&noise_rivers->np, x, z, seed); + float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed); + float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed); + + tn.x = x; + tn.z = z; + tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed); + tn.rivers = &rivers; + tn.valley = &valley; + tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed); + tn.slope = &inter_valley_slope; + tn.inter_valley_fill = 0.f; + tn.cliffs = 0.f; + tn.corr = 0.f; + + if (fast_terrain) { + tn.inter_valley_fill = NoisePerlin2D(&noise_inter_valley_fill->np, x, z, seed); + + if (cliff_terrain) + tn.cliffs = NoisePerlin2D(&noise_cliffs->np, x, z, seed); + if (rugged_terrain) + tn.corr = NoisePerlin2D(&noise_corr->np, x, z, seed); + } + + return adjustedTerrainLevelFromNoise(&tn); +} + + +int MapgenValleys::generateTerrain() +{ + MapNode n_air(CONTENT_AIR); + MapNode n_river_water(c_river_water_source); + MapNode n_sand(c_sand); + MapNode n_stone(c_stone); + MapNode n_water(c_water_source); + + v3s16 em = vm->m_area.getExtent(); + s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index_2d = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { + s16 river_y = round(noise_rivers->result[index_2d]); + s16 surface_y = round(noise_terrain_height->result[index_2d]); + float slope = noise_inter_valley_slope->result[index_2d]; + + heightmap[index_2d] = surface_y; + + if (surface_y > surface_max_y) + surface_max_y = surface_y; + + u32 index_3d = 0; + if (!fast_terrain) + index_3d = (z - node_min.Z) * zstride + (x - node_min.X); + + u32 index_data = vm->m_area.index(x, node_min.Y - 1, z); + + // Mapgens concern themselves with stone and water. + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + float fill = 0.f; + if (!fast_terrain) + fill = noise_inter_valley_fill->result[index_3d]; + + if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) { + bool river = (river_y > surface_y); + + if (river && y == surface_y) { + // river bottom + vm->m_data[index_data] = n_sand; + } else if ((fast_terrain || river) && y <= surface_y) { + // ground + vm->m_data[index_data] = n_stone; + } else if (river && y < river_y) { + // river + vm->m_data[index_data] = n_river_water; + } else if ((!fast_terrain) && (!river) && fill * slope > y - surface_y) { + // ground (slow method) + vm->m_data[index_data] = n_stone; + heightmap[index_2d] = surface_max_y = y; + } else if (y <= water_level) { + // sea + vm->m_data[index_data] = n_water; + } else { + vm->m_data[index_data] = n_air; + } + } + + vm->m_area.add_y(em, index_data, 1); + if (!fast_terrain) + index_3d += ystride; + } + + if (!fast_terrain) { + // Assign the humidity adjusted by water proximity. + noise_humidity->result[index_2d] = humidityByTerrain( + noise_humidity->result[index_2d], + surface_max_y, + noise_rivers->result[index_2d], + noise_valley_depth->result[index_2d]); + + // Assign the heat adjusted by altitude. See humidity, above. + if (use_altitude_chill && surface_max_y > 0) + noise_heat->result[index_2d] + *= pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill); + } + } + + return surface_max_y; +} + + +MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map) +{ + v3s16 em = vm->m_area.getExtent(); + u32 index = 0; + MgStoneType stone_type = STONE; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + Biome *biome = NULL; + u16 depth_top = 0; + u16 base_filler = 0; + u16 depth_water_top = 0; + u32 vi = vm->m_area.index(x, node_max.Y, z); + + // Check node at base of mapchunk above, either a node of a previously + // generated mapchunk or if not, a node of overgenerated base terrain. + content_t c_above = vm->m_data[vi + em.X].getContent(); + bool air_above = c_above == CONTENT_AIR; + bool water_above = (c_above == c_water_source); + + // If there is air or water above enable top/filler placement, otherwise force + // nplaced to stone level by setting a number exceeding any possible filler depth. + u16 nplaced = (air_above || water_above) ? 0 : U16_MAX; + + for (s16 y = node_max.Y; y >= node_min.Y; y--) { + content_t c = vm->m_data[vi].getContent(); + + // Biome is recalculated each time an upper surface is detected while + // working down a column. The selected biome then remains in effect for + // all nodes below until the next surface and biome recalculation. + // Biome is recalculated: + // 1. At the surface of stone below air or water. + // 2. At the surface of water below air. + // 3. When stone or water is detected but biome has not yet been calculated. + if ((c == c_stone && (air_above || water_above || !biome)) + || ((c == c_water_source || c == c_river_water_source) + && (air_above || !biome))) { + // Both heat and humidity have already been adjusted for altitude. + biome = bmgr->getBiome(heat_map[index], humidity_map[index], y); + + depth_top = biome->depth_top; + base_filler = MYMAX(depth_top + + biome->depth_filler + + noise_filler_depth->result[index], 0.f); + depth_water_top = biome->depth_water_top; + + // Detect stone type for dungeons during every biome calculation. + // This is more efficient than detecting per-node and will not + // miss any desert stone or sandstone biomes. + if (biome->c_stone == c_desert_stone) + stone_type = DESERT_STONE; + else if (biome->c_stone == c_sandstone) + stone_type = SANDSTONE; + } + + if (c == c_stone) { + content_t c_below = vm->m_data[vi - em.X].getContent(); + + // If the node below isn't solid, make this node stone, so that + // any top/filler nodes above are structurally supported. + // This is done by aborting the cycle of top/filler placement + // immediately by forcing nplaced to stone level. + if (c_below == CONTENT_AIR + || c_below == c_water_source + || c_below == c_river_water_source) + nplaced = U16_MAX; + + if (nplaced < depth_top) { + vm->m_data[vi] = MapNode(biome->c_top); + nplaced++; + } else if (nplaced < base_filler) { + vm->m_data[vi] = MapNode(biome->c_filler); + nplaced++; + } else { + vm->m_data[vi] = MapNode(biome->c_stone); + } + + air_above = false; + water_above = false; + } else if (c == c_water_source) { + vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) + ? biome->c_water_top : biome->c_water); + nplaced = 0; // Enable top/filler placement for next surface + air_above = false; + water_above = true; + } else if (c == c_river_water_source) { + vm->m_data[vi] = MapNode(biome->c_river_water); + nplaced = U16_MAX; // Sand was already placed under rivers. + air_above = false; + water_above = true; + } else if (c == CONTENT_AIR) { + nplaced = 0; // Enable top/filler placement for next surface + air_above = true; + water_above = false; + } else { // Possible various nodes overgenerated from neighbouring mapchunks + nplaced = U16_MAX; // Disable top/filler placement + air_above = false; + water_above = false; + } + + vm->m_area.add_y(em, vi, -1); + } + } + + return stone_type; +} + + +void MapgenValleys::dustTopNodes() +{ + if (node_max.Y < water_level) + return; + + v3s16 em = vm->m_area.getExtent(); + u32 index = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index++) { + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]); + + if (biome->c_dust == CONTENT_IGNORE) + continue; + + u32 vi = vm->m_area.index(x, full_node_max.Y, z); + content_t c_full_max = vm->m_data[vi].getContent(); + s16 y_start; + + if (c_full_max == CONTENT_AIR) { + y_start = full_node_max.Y - 1; + } else if (c_full_max == CONTENT_IGNORE) { + vi = vm->m_area.index(x, node_max.Y + 1, z); + content_t c_max = vm->m_data[vi].getContent(); + + if (c_max == CONTENT_AIR) + y_start = node_max.Y; + else + continue; + } else { + continue; + } + + vi = vm->m_area.index(x, y_start, z); + for (s16 y = y_start; y >= node_min.Y - 1; y--) { + if (vm->m_data[vi].getContent() != CONTENT_AIR) + break; + + vm->m_area.add_y(em, vi, -1); + } + + content_t c = vm->m_data[vi].getContent(); + if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) { + vm->m_area.add_y(em, vi, 1); + vm->m_data[vi] = MapNode(biome->c_dust); + } + } +} + + +void MapgenValleys::generateSimpleCaves(s16 max_stone_y) +{ + PseudoRandom ps(blockseed + 72202); + + MapNode n_air(CONTENT_AIR); + MapNode n_dirt(c_dirt); + MapNode n_lava(c_lava_source); + MapNode n_water(c_river_water_source); + + v3s16 em = vm->m_area.getExtent(); + + s16 base_water_chance = 0; + if (water_features < 11) + base_water_chance = ceil(MAX_MAP_GENERATION_LIMIT / (water_features * 1000)); + + if (max_stone_y >= node_min.Y) { + u32 index_2d = 0; + u32 index_3d = 0; + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { + bool air_above = false; + //bool underground = false; + u32 index_data = vm->m_area.index(x, node_max.Y + 1, z); + + index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X); + + // Dig caves on down loop to check for air above. + for (s16 y = node_max.Y + 1; + y >= node_min.Y - 1; + y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) { + float terrain = noise_terrain_height->result[index_2d]; + + // Saves some time and prevents removing above ground nodes. + if (y > terrain + 1) { + air_above = true; + continue; + } + + content_t c = vm->m_data[index_data].getContent(); + bool n1 = (fabs(noise_simple_caves_1->result[index_3d]) < 0.07f); + bool n2 = (fabs(noise_simple_caves_2->result[index_3d]) < 0.07f); + + // River water is (foolishly) not set as ground content + // in the default game. This can produce strange results + // when a cave undercuts a river. However, that's not for + // the mapgen to correct. Fix it in lua. + + if (c == CONTENT_AIR) { + air_above = true; + } else if (n1 && n2 && ndef->get(c).is_ground_content) { + // When both n's are true, we're in a cave. + vm->m_data[index_data] = n_air; + air_above = true; + } else if (air_above + && (c == c_stone || c == c_sandstone || c == c_desert_stone)) { + // At the cave floor + s16 sr = ps.next() & 1023; + u32 j = index_data; + vm->m_area.add_y(em, j, 1); + + if (sr > (terrain - y) * 25) { + // Put dirt in caves near the surface. + Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); + vm->m_data[index_data] = MapNode(biome->c_filler); + } else { + s16 lava_chance = 0; + + if (y <= lava_max_height && c == c_stone) { + // Lava spawns increase with depth. + lava_chance = ceil((lava_max_height - y + 1) / 10000); + + if (sr < lava_chance) + vm->m_data[j] = n_lava; + } + + if (base_water_chance > 0 && y <= cave_water_max_height) { + s16 water_chance = base_water_chance + - (abs(y - water_level) / (water_features * 1000)); + + // Waterfalls may get out of control above ground. + sr -= lava_chance; + // If sr < 0 then we should have already placed lava -- + // don't immediately dump water on it. + if (sr >= 0 && sr < water_chance) + vm->m_data[j] = n_water; + } + } + + air_above = false; + } + + // If we're not in a cave, there's no open space. + if (!(n1 && n2)) + air_above = false; + } + } + } +} diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h new file mode 100644 index 000000000..9c08b16d1 --- /dev/null +++ b/src/mapgen_valleys.h @@ -0,0 +1,194 @@ +/* +Minetest Valleys C +Copyright (C) 2010-2015 kwolekr, Ryan Kwolek +Copyright (C) 2010-2015 paramat, Matt Gregory +Copyright (C) 2016 Duane Robertson + +Based on Valleys Mapgen by Gael de Sailly + (https://forum.minetest.net/viewtopic.php?f=9&t=11430) +and mapgen_v7 by kwolekr and paramat. + +Licensing changed by permission of Gael de Sailly. + +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 MAPGEN_VALLEYS_HEADER +#define MAPGEN_VALLEYS_HEADER + +#include "mapgen.h" + +/////////////////// Mapgen Valleys flags +#define MG_VALLEYS_ALT_CHILL 0x01 +#define MG_VALLEYS_CLIFFS 0x02 +#define MG_VALLEYS_FAST 0x04 +#define MG_VALLEYS_HUMID_RIVERS 0x08 +#define MG_VALLEYS_RUGGED 0x10 + +class BiomeManager; + +// Global profiler +//class Profiler; +//extern Profiler *mapgen_profiler; + + +struct MapgenValleysParams : public MapgenSpecificParams { + u32 spflags; + + u16 altitude_chill; + s16 cave_water_max_height; + s16 humidity; + s16 humidity_break_point; + s16 lava_max_height; + u16 river_depth; + u16 river_size; + s16 temperature; + u16 water_features; + + NoiseParams np_biome_heat; + NoiseParams np_biome_heat_blend; + NoiseParams np_biome_humidity; + NoiseParams np_biome_humidity_blend; + NoiseParams np_cliffs; + NoiseParams np_corr; + NoiseParams np_filler_depth; + NoiseParams np_inter_valley_fill; + NoiseParams np_inter_valley_slope; + NoiseParams np_rivers; + NoiseParams np_simple_caves_1; + NoiseParams np_simple_caves_2; + NoiseParams np_terrain_height; + NoiseParams np_valley_depth; + NoiseParams np_valley_profile; + + MapgenValleysParams(); + ~MapgenValleysParams() {} + + void readParams(const Settings *settings); + void writeParams(Settings *settings) const; +}; + +struct TerrainNoise { + s16 x; + s16 z; + float terrain_height; + float *rivers; + float *valley; + float valley_profile; + float *slope; + float inter_valley_fill; + float cliffs; + float corr; +}; + +class MapgenValleys : public Mapgen { +public: + + MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge); + ~MapgenValleys(); + + virtual void makeChunk(BlockMakeData *data); + inline int getGroundLevelAtPoint(v2s16 p); + +private: + EmergeManager *m_emerge; + BiomeManager *bmgr; + + int ystride; + int zstride; + + u32 spflags; + bool cliff_terrain; + bool fast_terrain; + bool rugged_terrain; + bool humid_rivers; + bool use_altitude_chill; + + v3s16 node_min; + v3s16 node_max; + v3s16 full_node_min; + v3s16 full_node_max; + + Noise *noise_filler_depth; + + Noise *noise_cliffs; + Noise *noise_corr; + Noise *noise_heat; + Noise *noise_heat_blend; + Noise *noise_humidity; + Noise *noise_humidity_blend; + Noise *noise_inter_valley_fill; + Noise *noise_inter_valley_slope; + Noise *noise_rivers; + Noise *noise_simple_caves_1; + Noise *noise_simple_caves_2; + Noise *noise_terrain_height; + Noise *noise_valley_depth; + Noise *noise_valley_profile; + + float altitude_chill; + float cave_water_max_height; + float humidity_adjust; + float humidity_break_point; + float lava_max_height; + float river_depth; + float river_size; + float temperature_adjust; + s16 water_features; + + content_t c_cobble; + content_t c_desert_stone; + content_t c_dirt; + content_t c_ice; + content_t c_lava_source; + content_t c_mossycobble; + content_t c_river_water_source; + content_t c_sand; + content_t c_sandstone; + content_t c_sandstonebrick; + content_t c_stair_cobble; + content_t c_stair_sandstonebrick; + content_t c_stone; + content_t c_water_source; + + float terrainLevelAtPoint(s16 x, s16 z); + + void calculateNoise(); + + virtual int generateTerrain(); + float terrainLevelFromNoise(TerrainNoise *tn); + float adjustedTerrainLevelFromNoise(TerrainNoise *tn); + + float humidityByTerrain(float humidity_base, float mount, float rivers, float valley); + + MgStoneType generateBiomes(float *heat_map, float *humidity_map); + void dustTopNodes(); + + void generateSimpleCaves(s16 max_stone_y); +}; + +struct MapgenFactoryValleys : public MapgenFactory { + Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) + { + return new MapgenValleys(mgid, params, emerge); + }; + + MapgenSpecificParams *createMapgenParams() + { + return new MapgenValleysParams(); + }; +}; + +#endif From da686160c33069b77a7b4c31fd97da5fa5b59baa Mon Sep 17 00:00:00 2001 From: Kahrl Date: Fri, 15 Jan 2016 02:16:21 +0100 Subject: [PATCH 37/68] Make all mesh manipulators in mesh.cpp work with any vertex type cloneMesh() has to use a switch in order to create a different mesh buffer type depending on vertex type. (Credit: the new cloneMesh was written by RealBadAngel.) To avoid repetitive code, all other methods use getVertexPitchFromType() to automatically adapt the indexing to the vertex type at runtime. --- src/mesh.cpp | 269 +++++++++++++++++++++++++++------------------------ 1 file changed, 145 insertions(+), 124 deletions(-) diff --git a/src/mesh.cpp b/src/mesh.cpp index 329b93dc9..a800ddf1e 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -206,146 +206,139 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh, const video::SColor &colorY, const video::SColor &colorZ) { - if(mesh == NULL) + if (mesh == NULL) return; - + u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; i= y && x >= z) - vertices[i].Color = colorX; - else if(y >= z) - vertices[i].Color = colorY; + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) { + video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); + f32 x = fabs(vertex->Normal.X); + f32 y = fabs(vertex->Normal.Y); + f32 z = fabs(vertex->Normal.Z); + if (x >= y && x >= z) + vertex->Color = colorX; + else if (y >= z) + vertex->Color = colorY; else - vertices[i].Color = colorZ; + vertex->Color = colorZ; } } } -void rotateMeshXYby (scene::IMesh *mesh, f64 degrees) -{ +void rotateMeshXYby(scene::IMesh *mesh, f64 degrees) +{ u16 mc = mesh->getMeshBufferCount(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateXYBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateXYBy(degrees); } } -void rotateMeshXZby (scene::IMesh *mesh, f64 degrees) -{ +void rotateMeshXZby(scene::IMesh *mesh, f64 degrees) +{ u16 mc = mesh->getMeshBufferCount(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateXZBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateXZBy(degrees); } } -void rotateMeshYZby (scene::IMesh *mesh, f64 degrees) -{ +void rotateMeshYZby(scene::IMesh *mesh, f64 degrees) +{ u16 mc = mesh->getMeshBufferCount(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateYZBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateYZBy(degrees); } } void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) -{ - int axisdir = facedir>>2; +{ + int axisdir = facedir >> 2; facedir &= 0x03; u16 mc = mesh->getMeshBufferCount(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) { + video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); + switch (axisdir) { + case 0: + if (facedir == 1) + vertex->Pos.rotateXZBy(-90); + else if (facedir == 2) + vertex->Pos.rotateXZBy(180); + else if (facedir == 3) + vertex->Pos.rotateXZBy(90); + break; + case 1: // z+ + vertex->Pos.rotateYZBy(90); + if (facedir == 1) + vertex->Pos.rotateXYBy(90); + else if (facedir == 2) + vertex->Pos.rotateXYBy(180); + else if (facedir == 3) + vertex->Pos.rotateXYBy(-90); + break; + case 2: //z- + vertex->Pos.rotateYZBy(-90); + if (facedir == 1) + vertex->Pos.rotateXYBy(-90); + else if (facedir == 2) + vertex->Pos.rotateXYBy(180); + else if (facedir == 3) + vertex->Pos.rotateXYBy(90); + break; + case 3: //x+ + vertex->Pos.rotateXYBy(-90); + if (facedir == 1) + vertex->Pos.rotateYZBy(90); + else if (facedir == 2) + vertex->Pos.rotateYZBy(180); + else if (facedir == 3) + vertex->Pos.rotateYZBy(-90); + break; + case 4: //x- + vertex->Pos.rotateXYBy(90); + if (facedir == 1) + vertex->Pos.rotateYZBy(-90); + else if (facedir == 2) + vertex->Pos.rotateYZBy(180); + else if (facedir == 3) + vertex->Pos.rotateYZBy(90); + break; + case 5: + vertex->Pos.rotateXYBy(-180); + if (facedir == 1) + vertex->Pos.rotateXZBy(90); + else if (facedir == 2) + vertex->Pos.rotateXZBy(180); + else if (facedir == 3) + vertex->Pos.rotateXZBy(-90); + break; + default: + break; } } } @@ -355,11 +348,10 @@ void recalculateBoundingBox(scene::IMesh *src_mesh) { core::aabbox3d bbox; bbox.reset(0,0,0); - for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) - { + for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j); buf->recalculateBoundingBox(); - if(j == 0) + if (j == 0) bbox = buf->getBoundingBox(); else bbox.addInternalBox(buf->getBoundingBox()); @@ -370,18 +362,47 @@ void recalculateBoundingBox(scene::IMesh *src_mesh) scene::IMesh* cloneMesh(scene::IMesh *src_mesh) { scene::SMesh* dst_mesh = new scene::SMesh(); - for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) - { + for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) { scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 *indices = (u16*)buf->getIndices(); - scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); - temp_buf->append(vertices, buf->getVertexCount(), - indices, buf->getIndexCount()); - dst_mesh->addMeshBuffer(temp_buf); - temp_buf->drop(); + switch (buf->getVertexType()) { + case video::EVT_STANDARD: { + video::S3DVertex *v = + (video::S3DVertex *) buf->getVertices(); + u16 *indices = (u16*)buf->getIndices(); + scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); + temp_buf->append(v, buf->getVertexCount(), + indices, buf->getIndexCount()); + dst_mesh->addMeshBuffer(temp_buf); + temp_buf->drop(); + break; + } + case video::EVT_2TCOORDS: { + video::S3DVertex2TCoords *v = + (video::S3DVertex2TCoords *) buf->getVertices(); + u16 *indices = (u16*)buf->getIndices(); + scene::SMeshBufferTangents *temp_buf = + new scene::SMeshBufferTangents(); + temp_buf->append(v, buf->getVertexCount(), + indices, buf->getIndexCount()); + dst_mesh->addMeshBuffer(temp_buf); + temp_buf->drop(); + break; + } + case video::EVT_TANGENTS: { + video::S3DVertexTangents *v = + (video::S3DVertexTangents *) buf->getVertices(); + u16 *indices = (u16*)buf->getIndices(); + scene::SMeshBufferTangents *temp_buf = + new scene::SMeshBufferTangents(); + temp_buf->append(v, buf->getVertexCount(), + indices, buf->getIndexCount()); + dst_mesh->addMeshBuffer(temp_buf); + temp_buf->drop(); + break; + } + } } - return dst_mesh; + return dst_mesh; } scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f) From a58c0f458d336fdab59737c754661e4f16818d99 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 15 Jan 2016 13:40:59 +0100 Subject: [PATCH 38/68] Make ItemStack:set_count(0) clear the item stack fixes minetest/minetest_game#786 --- src/script/lua_api/l_item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 842b15709..5381cba76 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -94,7 +94,7 @@ int LuaItemStack::l_set_count(lua_State *L) bool status; lua_Integer count = luaL_checkinteger(L, 2); - if (count <= 65535) { + if (count > 0 && count <= 65535) { item.count = count; status = true; } else { From 752d8202061b1092daacb1f7056ace4d5aabef01 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Sat, 16 Jan 2016 03:53:02 -0600 Subject: [PATCH 39/68] Prevent spawning in rivers with valleys mapgen. Remove unecessary whitespace. --- src/mapgen_valleys.cpp | 88 ++++++++++++++++++++++++------------------ src/mapgen_valleys.h | 20 +++++----- 2 files changed, 61 insertions(+), 47 deletions(-) diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index c14ceb51e..93f47cd5f 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -185,19 +185,19 @@ MapgenValleys::~MapgenValleys() MapgenValleysParams::MapgenValleysParams() { spflags = MG_VALLEYS_CLIFFS | MG_VALLEYS_RUGGED - | MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL; + | MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL; - altitude_chill = 90; // The altitude at which temperature drops by 20C. + altitude_chill = 90; // The altitude at which temperature drops by 20C. // Water in caves will never be higher than this. - cave_water_max_height = MAX_MAP_GENERATION_LIMIT; - humidity = 50; + cave_water_max_height = MAX_MAP_GENERATION_LIMIT; + humidity = 50; // the maximum humidity around rivers in otherwise dry areas - humidity_break_point = 65; - lava_max_height = 0; // Lava will never be higher than this. - river_depth = 4; // How deep to carve river channels. - river_size = 5; // How wide to make rivers. - temperature = 50; - water_features = 3; // How often water will occur in caves. + humidity_break_point = 65; + lava_max_height = 0; // Lava will never be higher than this. + river_depth = 4; // How deep to carve river channels. + river_size = 5; // How wide to make rivers. + temperature = 50; + water_features = 3; // How often water will occur in caves. np_cliffs = NoiseParams(0.f, 1.f, v3f(750, 750, 750), 8445, 5, 1.f, 2.f); np_corr = NoiseParams(0.f, 1.f, v3f(40, 40, 40), -3536, 4, 1.f, 2.f); @@ -285,7 +285,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) data->blockpos_requested.Z <= data->blockpos_max.Z); this->generating = true; - this->vm = data->vmanip; + this->vm = data->vmanip; this->ndef = data->nodedef; //TimeTaker t("makeChunk"); @@ -375,9 +375,9 @@ void MapgenValleys::makeChunk(BlockMakeData *data) if (flags & MG_LIGHT) calcLighting( - node_min - v3s16(0, 1, 0), - node_max + v3s16(0, 1, 0), - full_node_min, + node_min - v3s16(0, 1, 0), + node_max + v3s16(0, 1, 0), + full_node_min, full_node_max); //mapgen_profiler->avg("liquid_lighting", tll.stop() / 1000.f); @@ -535,7 +535,7 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) } if (fast_terrain) { - // The penultimate step builds up the heights, but we reduce it + // The penultimate step builds up the heights, but we reduce it // occasionally to create cliffs. float delta = sin(tn->inter_valley_fill) * *tn->slope; if (cliff_terrain && tn->cliffs >= 0.2f) @@ -544,8 +544,8 @@ float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn) mount += delta; // Use yet another noise to make the heights look more rugged. - if (rugged_terrain - && mount > water_level + if (rugged_terrain + && mount > water_level && fabs(inter_valley_slope * tn->inter_valley_fill) < 0.3f) mount += ((delta < 0.f) ? -1.f : 1.f) * pow(fabs(delta), 0.5f) * fabs(sin(tn->corr)); } @@ -576,9 +576,9 @@ float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) float MapgenValleys::humidityByTerrain( - float humidity_base, - float mount, - float rivers, + float humidity_base, + float mount, + float rivers, float valley) { // Although the original valleys adjusts humidity by distance @@ -603,9 +603,23 @@ float MapgenValleys::humidityByTerrain( } -inline int MapgenValleys::getGroundLevelAtPoint(v2s16 p) +int MapgenValleys::getGroundLevelAtPoint(v2s16 p) { - // Base terrain calculation + // *********************************************** + // This method (deliberately) does not return correct + // terrain values. This may be a problem in the future. + // *********************************************** + + // Since MT doesn't normally deal with rivers, check + // to make sure this isn't a request for a location + // in a river. + float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed); + + // If it's wet, return an unusable number. + if (fabs(rivers) < river_size) + return MAX_MAP_GENERATION_LIMIT; + + // Otherwise, return the real result. return terrainLevelAtPoint(p.X, p.Y); } @@ -709,14 +723,14 @@ int MapgenValleys::generateTerrain() if (!fast_terrain) { // Assign the humidity adjusted by water proximity. noise_humidity->result[index_2d] = humidityByTerrain( - noise_humidity->result[index_2d], - surface_max_y, - noise_rivers->result[index_2d], + noise_humidity->result[index_2d], + surface_max_y, + noise_rivers->result[index_2d], noise_valley_depth->result[index_2d]); // Assign the heat adjusted by altitude. See humidity, above. if (use_altitude_chill && surface_max_y > 0) - noise_heat->result[index_2d] + noise_heat->result[index_2d] *= pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill); } } @@ -759,15 +773,15 @@ MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map) // 1. At the surface of stone below air or water. // 2. At the surface of water below air. // 3. When stone or water is detected but biome has not yet been calculated. - if ((c == c_stone && (air_above || water_above || !biome)) - || ((c == c_water_source || c == c_river_water_source) + if ((c == c_stone && (air_above || water_above || !biome)) + || ((c == c_water_source || c == c_river_water_source) && (air_above || !biome))) { // Both heat and humidity have already been adjusted for altitude. biome = bmgr->getBiome(heat_map[index], humidity_map[index], y); depth_top = biome->depth_top; - base_filler = MYMAX(depth_top - + biome->depth_filler + base_filler = MYMAX(depth_top + + biome->depth_filler + noise_filler_depth->result[index], 0.f); depth_water_top = biome->depth_water_top; @@ -787,8 +801,8 @@ MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map) // any top/filler nodes above are structurally supported. // This is done by aborting the cycle of top/filler placement // immediately by forcing nplaced to stone level. - if (c_below == CONTENT_AIR - || c_below == c_water_source + if (c_below == CONTENT_AIR + || c_below == c_water_source || c_below == c_river_water_source) nplaced = U16_MAX; @@ -805,7 +819,7 @@ MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map) air_above = false; water_above = false; } else if (c == c_water_source) { - vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) + vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) ? biome->c_water_top : biome->c_water); nplaced = 0; // Enable top/filler placement for next surface air_above = false; @@ -910,8 +924,8 @@ void MapgenValleys::generateSimpleCaves(s16 max_stone_y) index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X); // Dig caves on down loop to check for air above. - for (s16 y = node_max.Y + 1; - y >= node_min.Y - 1; + for (s16 y = node_max.Y + 1; + y >= node_min.Y - 1; y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) { float terrain = noise_terrain_height->result[index_2d]; @@ -936,7 +950,7 @@ void MapgenValleys::generateSimpleCaves(s16 max_stone_y) // When both n's are true, we're in a cave. vm->m_data[index_data] = n_air; air_above = true; - } else if (air_above + } else if (air_above && (c == c_stone || c == c_sandstone || c == c_desert_stone)) { // At the cave floor s16 sr = ps.next() & 1023; @@ -959,7 +973,7 @@ void MapgenValleys::generateSimpleCaves(s16 max_stone_y) } if (base_water_chance > 0 && y <= cave_water_max_height) { - s16 water_chance = base_water_chance + s16 water_chance = base_water_chance - (abs(y - water_level) / (water_features * 1000)); // Waterfalls may get out of control above ground. diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 9c08b16d1..5fd549096 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -81,15 +81,15 @@ struct MapgenValleysParams : public MapgenSpecificParams { }; struct TerrainNoise { - s16 x; - s16 z; - float terrain_height; - float *rivers; - float *valley; - float valley_profile; - float *slope; - float inter_valley_fill; - float cliffs; + s16 x; + s16 z; + float terrain_height; + float *rivers; + float *valley; + float valley_profile; + float *slope; + float inter_valley_fill; + float cliffs; float corr; }; @@ -100,7 +100,7 @@ public: ~MapgenValleys(); virtual void makeChunk(BlockMakeData *data); - inline int getGroundLevelAtPoint(v2s16 p); + int getGroundLevelAtPoint(v2s16 p); private: EmergeManager *m_emerge; From 487ab593d031bf310bd76b3edfe2ad42c1e248b5 Mon Sep 17 00:00:00 2001 From: Rogier Date: Fri, 8 Jan 2016 09:29:39 +0100 Subject: [PATCH 40/68] Fix error message in settings tab overlapping 'save' button The save button is now fully functional again when an error message is shown. After an invalid value is entered in the settings tab dialog, the GUI label for the error message that is shown was partly overlapping the 'save' button, so that the top half of the button could not be clicked on. --- builtin/mainmenu/tab_settings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 472becea2..99138a091 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -445,7 +445,7 @@ local function create_change_setting_formspec(dialogdata) if dialogdata.error_message then formspec = formspec .. "tablecolumns[color;text]" .. "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. - "table[5,4;5,1;error_message;#FF0000," + "table[5,3.9;5,0.6;error_message;#FF0000," .. core.formspec_escape(dialogdata.error_message) .. ";0]" width = 5 if dialogdata.entered_text then From 22bc66d3a7b96f0742669a988b45d07d58e32928 Mon Sep 17 00:00:00 2001 From: Pinky Snow Date: Sat, 16 Jan 2016 05:23:00 -0500 Subject: [PATCH 41/68] corrected minetest.pos_to_string() corrected this bit reflect the function properly. --- doc/lua_api.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index a3bb64818..0ff8f031d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1715,8 +1715,9 @@ Helper functions * e.g. `string:split("a,b", ",") == {"a","b"}` * `string:trim()` * e.g. `string.trim("\n \t\tfoo bar\t ") == "foo bar"` -* `minetest.pos_to_string({x=X,y=Y,z=Z})`: returns `"(X,Y,Z)"` +* `minetest.pos_to_string({x=X,y=Y,z=Z}, decimal_places))`: returns `"(X,Y,Z)"` * Convert position to a printable string + Optional: 'decimal_places' will round the x, y and z of the pos to the given decimal place. * `minetest.string_to_pos(string)`: returns a position * Same but in reverse. Returns `nil` if the string can't be parsed to a position. * `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions From 13e7589fecfc8b6c247839ddaac66e9d045e513c Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 18 Jan 2016 06:08:54 +0100 Subject: [PATCH 42/68] Fix wield item glitch --- src/camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/camera.cpp b/src/camera.cpp index 0b3413591..94bbe9880 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -646,7 +646,7 @@ void Camera::drawWieldedTool(irr::core::matrix4* translation) scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera(); cam->setAspectRatio(m_cameranode->getAspectRatio()); cam->setFOV(72.0*M_PI/180.0); - cam->setNearValue(0.1); + cam->setNearValue(10); cam->setFarValue(1000); if (translation != NULL) { From eb6e2c11b16c9ef5287bda224fa965a37ef49131 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Mon, 18 Jan 2016 01:55:08 -0600 Subject: [PATCH 43/68] Correct overflowing rivers in Valleys mapgen. --- src/mapgen_valleys.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 93f47cd5f..6f4b2ccc7 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -670,8 +670,8 @@ int MapgenValleys::generateTerrain() for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { - s16 river_y = round(noise_rivers->result[index_2d]); - s16 surface_y = round(noise_terrain_height->result[index_2d]); + s16 river_y = floor(noise_rivers->result[index_2d]); + s16 surface_y = floor(noise_terrain_height->result[index_2d]); float slope = noise_inter_valley_slope->result[index_2d]; heightmap[index_2d] = surface_y; @@ -703,7 +703,7 @@ int MapgenValleys::generateTerrain() } else if (river && y < river_y) { // river vm->m_data[index_data] = n_river_water; - } else if ((!fast_terrain) && (!river) && fill * slope > y - surface_y) { + } else if ((!fast_terrain) && (!river) && round(fill * slope) >= y - surface_y) { // ground (slow method) vm->m_data[index_data] = n_stone; heightmap[index_2d] = surface_max_y = y; From 87291ea44a61614d5bd9efc0657926da3f867b5f Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Fri, 8 Jan 2016 15:59:36 +0100 Subject: [PATCH 44/68] Show infotext with description for item entities --- builtin/game/item_entity.lua | 4 ++++ doc/lua_api.txt | 1 + src/content_cao.h | 5 +++++ src/game.cpp | 7 +++++-- src/object_properties.cpp | 2 ++ src/object_properties.h | 1 + src/script/common/c_content.cpp | 3 +++ 7 files changed, 21 insertions(+), 2 deletions(-) diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua index be158c119..a66bf33d0 100644 --- a/builtin/game/item_entity.lua +++ b/builtin/game/item_entity.lua @@ -31,6 +31,7 @@ core.register_entity(":__builtin:item", { spritediv = {x = 1, y = 1}, initial_sprite_basepos = {x = 0, y = 0}, is_visible = false, + infotext = "", }, itemstring = '', @@ -50,6 +51,7 @@ core.register_entity(":__builtin:item", { local c = s local itemtable = stack:to_table() local itemname = nil + local description = "" if itemtable then itemname = stack:to_table().name end @@ -58,6 +60,7 @@ core.register_entity(":__builtin:item", { if core.registered_items[itemname] then item_texture = core.registered_items[itemname].inventory_image item_type = core.registered_items[itemname].type + description = core.registered_items[itemname].description end local prop = { is_visible = true, @@ -66,6 +69,7 @@ core.register_entity(":__builtin:item", { visual_size = {x = s, y = s}, collisionbox = {-c, -c, -c, c, c, c}, automatic_rotate = math.pi * 0.5, + infotext = description, } self.object:set_properties(prop) end, diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 0ff8f031d..c2d5183d7 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3241,6 +3241,7 @@ Definition tables backface_culling = true, -- false to disable backface_culling for model nametag = "", -- by default empty, for players their name is shown if empty nametag_color = , -- sets color of nametag as ColorSpec + infotext = "", -- by default empty, text to be shown when pointed at object } ### Entity definition (`register_entity`) diff --git a/src/content_cao.h b/src/content_cao.h index d9145c5f1..abb242aa4 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -201,6 +201,11 @@ public: float time_from_last_punch=1000000); std::string debugInfoText(); + + std::string infoText() + { + return m_prop.infotext; + } }; diff --git a/src/game.cpp b/src/game.cpp index 92d919931..3902c50bb 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3732,8 +3732,11 @@ void Game::handlePointingAtObject(GameRunData *runData, { infotext = utf8_to_wide(runData->selected_object->infoText()); - if (infotext == L"" && show_debug) { - infotext = utf8_to_wide(runData->selected_object->debugInfoText()); + if (show_debug) { + if (infotext != L"") { + infotext += L"\n"; + } + infotext += utf8_to_wide(runData->selected_object->debugInfoText()); } if (input->getLeftState()) { diff --git a/src/object_properties.cpp b/src/object_properties.cpp index abd1bbd09..89ca26274 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -118,6 +118,7 @@ void ObjectProperties::serialize(std::ostream &os) const os << serializeString(nametag); writeARGB8(os, nametag_color); writeF1000(os, automatic_face_movement_max_rotation_per_sec); + os << serializeString(infotext); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -159,6 +160,7 @@ void ObjectProperties::deSerialize(std::istream &is) nametag = deSerializeString(is); nametag_color = readARGB8(is); automatic_face_movement_max_rotation_per_sec = readF1000(is); + infotext = deSerializeString(is); }catch(SerializationError &e){} } else diff --git a/src/object_properties.h b/src/object_properties.h index 47698cff7..02ec9d1f7 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -51,6 +51,7 @@ struct ObjectProperties std::string nametag; video::SColor nametag_color; f32 automatic_face_movement_max_rotation_per_sec; + std::string infotext; ObjectProperties(); std::string dump(); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 62de2c968..275b22bb8 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -216,6 +216,7 @@ void read_object_properties(lua_State *L, int index, prop->automatic_face_movement_max_rotation_per_sec = luaL_checknumber(L, -1); } lua_pop(L, 1); + getstringfield(L, -1, "infotext", prop->infotext); } /******************************************************************************/ @@ -282,6 +283,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "nametag_color"); lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec); lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec"); + lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size()); + lua_setfield(L, -2, "infotext"); } /******************************************************************************/ From b67eab3b0050a1f08d9c56138969d1a659ee7eac Mon Sep 17 00:00:00 2001 From: Kahrl Date: Tue, 19 Jan 2016 10:15:01 +0100 Subject: [PATCH 45/68] Fix Settings::remove() always returning true --- src/settings.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index e1e01e81a..8ea687d1c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -880,8 +880,14 @@ bool Settings::remove(const std::string &name) { MutexAutoLock lock(m_mutex); - delete m_settings[name].group; - return m_settings.erase(name); + std::map::iterator it = m_settings.find(name); + if (it != m_settings.end()) { + delete it->second.group; + m_settings.erase(it); + return true; + } else { + return false; + } } From 9f988e3b962389e10a7cf010fd4bf0f81d70e31a Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 14 Nov 2015 03:07:21 -0500 Subject: [PATCH 46/68] EmergeManager: Do not queue duplicate block requests --- src/emerge.cpp | 13 +++++++++---- src/emerge.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/emerge.cpp b/src/emerge.cpp index b188a7f41..ccb4c1703 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -292,14 +292,18 @@ bool EmergeManager::enqueueBlockEmergeEx( void *callback_param) { EmergeThread *thread = NULL; + bool entry_already_exists = false; { MutexAutoLock queuelock(m_queue_mutex); if (!pushBlockEmergeData(blockpos, peer_id, flags, - callback, callback_param)) + callback, callback_param, &entry_already_exists)) return false; + if (entry_already_exists) + return true; + thread = getOptimalThread(); thread->pushBlock(blockpos); } @@ -382,7 +386,8 @@ bool EmergeManager::pushBlockEmergeData( u16 peer_requested, u16 flags, EmergeCompletionCallback callback, - void *callback_param) + void *callback_param, + bool *entry_already_exists) { u16 &count_peer = m_peer_queue_count[peer_requested]; @@ -402,12 +407,12 @@ bool EmergeManager::pushBlockEmergeData( findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData())); BlockEmergeData &bedata = findres.first->second; - bool update_existing = !findres.second; + *entry_already_exists = !findres.second; if (callback) bedata.callbacks.push_back(std::make_pair(callback, callback_param)); - if (update_existing) { + if (*entry_already_exists) { bedata.flags |= flags; } else { bedata.flags = flags; diff --git a/src/emerge.h b/src/emerge.h index a143b660f..02bdf7e67 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -159,8 +159,15 @@ private: // Requires m_queue_mutex held EmergeThread *getOptimalThread(); - bool pushBlockEmergeData(v3s16 pos, u16 peer_requested, u16 flags, - EmergeCompletionCallback callback, void *callback_param); + + bool pushBlockEmergeData( + v3s16 pos, + u16 peer_requested, + u16 flags, + EmergeCompletionCallback callback, + void *callback_param, + bool *entry_already_exists); + bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata); friend class EmergeThread; From 882a89d65aa78b89cfaf2af054d15cc4c94ad022 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 18 Jan 2016 20:44:46 -0800 Subject: [PATCH 47/68] Allow per-tiles culling. Backface culling is enabled by default for all tiles, as this is how the lua parser initializes each tiledef. We revert to always using the value from the tiledef since it is always read and serialized. Mods that wish to enable culling for e.g. mesh nodes, now can specify the following to enable backface culling: tiles = {{ name = "tex.png", backface_culling = true }}, Note the double '{' and use of 'name' key here! In the same fashion, backface_culling can be disabled for any node now. I've tested this against the new door models and this properly allows me to disable culling per node. I've also tested this against my crops mod which uses mesh nodes where culling needs to be disabled, and tested also with plantlike drawtype nodes where we want this to continue to be disabled. No default setting has changed. The defaults are just migrated from nodedef.cpp to c_content.cpp. --- doc/lua_api.txt | 2 +- src/nodedef.cpp | 12 ++---------- src/script/common/c_content.cpp | 23 ++++++++++++++++++++--- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index c2d5183d7..e7c1b7dd5 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3358,7 +3358,7 @@ Definition tables * `{name="image.png", animation={Tile Animation definition}}` * `{name="image.png", backface_culling=bool, tileable_vertical=bool, tileable_horizontal=bool}` - * backface culling only supported in special tiles. + * backface culling enabled by default for most nodes * tileable flags are info for shaders, how they should treat texture when displacement mapping is used Directions are from the point of view of the tile texture, diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 2ebe1c131..0bcc00e47 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -843,12 +843,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, assert(f->liquid_type == LIQUID_SOURCE); if (opaque_water) f->alpha = 255; - if (new_style_water){ - f->solidness = 0; - } else { - f->solidness = 1; - f->backface_culling = false; - } + f->solidness = new_style_water ? 0 : 1; is_liquid = true; break; case NDT_FLOWINGLIQUID: @@ -899,17 +894,14 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, break; case NDT_PLANTLIKE: f->solidness = 0; - f->backface_culling = false; if (f->waving == 1) material_type = TILE_MATERIAL_WAVING_PLANTS; break; case NDT_FIRELIKE: - f->backface_culling = false; f->solidness = 0; break; case NDT_MESH: f->solidness = 0; - f->backface_culling = false; break; case NDT_TORCHLIKE: case NDT_SIGNLIKE: @@ -941,7 +933,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, // Tiles (fill in f->tiles[]) for (u16 j = 0; j < 6; j++) { fillTileAttribs(tsrc, &f->tiles[j], &tiledef[j], tile_shader[j], - use_normal_texture, f->backface_culling, f->alpha, material_type); + use_normal_texture, f->tiledef[j].backface_culling, f->alpha, material_type); } // Special tiles (fill in f->special_tiles[]) diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 275b22bb8..96fb78d99 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -294,14 +294,31 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) index = lua_gettop(L) + 1 + index; TileDef tiledef; - bool default_tiling = (drawtype == NDT_PLANTLIKE || drawtype == NDT_FIRELIKE) - ? false : true; + + bool default_tiling = true; + bool default_culling = true; + switch (drawtype) { + case NDT_PLANTLIKE: + case NDT_FIRELIKE: + default_tiling = false; + // "break" is omitted here intentionaly, as PLANTLIKE + // FIRELIKE drawtype both should default to having + // backface_culling to false. + case NDT_MESH: + case NDT_LIQUID: + default_culling = false; + break; + default: + break; + } + // key at index -2 and value at index if(lua_isstring(L, index)){ // "default_lava.png" tiledef.name = lua_tostring(L, index); tiledef.tileable_vertical = default_tiling; tiledef.tileable_horizontal = default_tiling; + tiledef.backface_culling = default_culling; } else if(lua_istable(L, index)) { @@ -310,7 +327,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) getstringfield(L, index, "name", tiledef.name); getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. tiledef.backface_culling = getboolfield_default( - L, index, "backface_culling", true); + L, index, "backface_culling", default_culling); tiledef.tileable_horizontal = getboolfield_default( L, index, "tileable_horizontal", default_tiling); tiledef.tileable_vertical = getboolfield_default( From 0459eca8eb2e73e9670e00b838dabc9347acb35f Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 17 Jan 2016 05:11:35 +0000 Subject: [PATCH 48/68] Liquid flow: Prevent water spreading on ignore --- src/map.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index ac29cfeee..409504232 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1732,11 +1732,14 @@ void Map::transformLiquids(std::map & modified_blocks) if (nb.t != NEIGHBOR_UPPER && liquid_type != LIQUID_NONE) m_transforming_liquid.push_back(npos); // if the current node happens to be a flowing node, it will start to flow down here. - if (nb.t == NEIGHBOR_LOWER) { + if (nb.t == NEIGHBOR_LOWER) flowing_down = true; - } } else { neutrals[num_neutrals++] = nb; + // If neutral below is ignore prevent water spreading outwards + if (nb.t == NEIGHBOR_LOWER && + nb.n.getContent() == CONTENT_IGNORE) + flowing_down = true; } break; case LIQUID_SOURCE: From e50c784e2ca55735fc360ae51534288c2ea59ca5 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 23 Jan 2016 05:45:00 +0100 Subject: [PATCH 49/68] Fix C++11 compilability Previous commits broke it... :( --- src/script/cpp_api/s_base.cpp | 2 +- src/script/cpp_api/s_base.h | 2 +- src/script/cpp_api/s_internal.h | 2 +- src/threading/event.h | 1 + src/threading/mutex.cpp | 15 +++++++++++++++ src/threading/mutex.h | 14 +++++++++++++- src/threading/mutex_auto_lock.h | 12 +++++++++++- 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 71369e3d7..679a517ee 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -68,7 +68,7 @@ public: */ ScriptApiBase::ScriptApiBase() : - m_luastackmutex(true) + m_luastackmutex() { #ifdef SCRIPTAPI_LOCK_DEBUG m_lock_recursion_count = 0; diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index d30373ce1..ead385a43 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -108,7 +108,7 @@ protected: void objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj); void objectrefGet(lua_State *L, u16 id); - Mutex m_luastackmutex; + RecursiveMutex m_luastackmutex; std::string m_last_run_mod; bool m_secure; #ifdef SCRIPTAPI_LOCK_DEBUG diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h index 651fed95f..37473c497 100644 --- a/src/script/cpp_api/s_internal.h +++ b/src/script/cpp_api/s_internal.h @@ -75,7 +75,7 @@ private: #endif #define SCRIPTAPI_PRECHECKHEADER \ - MutexAutoLock scriptlock(this->m_luastackmutex); \ + RecursiveMutexAutoLock scriptlock(this->m_luastackmutex); \ SCRIPTAPI_LOCK_CHECK; \ realityCheck(); \ lua_State *L = getStack(); \ diff --git a/src/threading/event.h b/src/threading/event.h index dba3ddb4c..43f2b04be 100644 --- a/src/threading/event.h +++ b/src/threading/event.h @@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L #include #include "threading/mutex.h" + #include "threading/mutex_auto_lock.h" #elif defined(_WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/threading/mutex.cpp b/src/threading/mutex.cpp index e12b79185..f2b07bec3 100644 --- a/src/threading/mutex.cpp +++ b/src/threading/mutex.cpp @@ -34,7 +34,18 @@ DEALINGS IN THE SOFTWARE. #define UNUSED(expr) do { (void)(expr); } while (0) +Mutex::Mutex() +{ + init_mutex(false); +} + + Mutex::Mutex(bool recursive) +{ + init_mutex(recursive); +} + +void Mutex::init_mutex(bool recursive) { #ifdef _WIN32 // Windows critical sections are recursive by default @@ -89,5 +100,9 @@ void Mutex::unlock() #endif } +RecursiveMutex::RecursiveMutex() + : Mutex(true) +{} + #endif diff --git a/src/threading/mutex.h b/src/threading/mutex.h index 40b10a2ea..dadbd050c 100644 --- a/src/threading/mutex.h +++ b/src/threading/mutex.h @@ -30,6 +30,7 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L && !defined(_WIN32) #include using Mutex = std::mutex; + using RecursiveMutex = std::recursive_mutex; #else #ifdef _WIN32 @@ -49,11 +50,14 @@ DEALINGS IN THE SOFTWARE. class Mutex { public: - Mutex(bool recursive=false); + Mutex(); ~Mutex(); void lock(); void unlock(); +protected: + Mutex(bool recursive); + void init_mutex(bool recursive); private: #ifdef _WIN32 CRITICAL_SECTION mutex; @@ -64,6 +68,14 @@ private: DISABLE_CLASS_COPY(Mutex); }; +class RecursiveMutex : public Mutex +{ +public: + RecursiveMutex(); + + DISABLE_CLASS_COPY(RecursiveMutex); +}; + #endif // C++11 #endif diff --git a/src/threading/mutex_auto_lock.h b/src/threading/mutex_auto_lock.h index 1c39349e5..25caf7e14 100644 --- a/src/threading/mutex_auto_lock.h +++ b/src/threading/mutex_auto_lock.h @@ -28,7 +28,8 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L #include - using MutexAutoLock = std::lock_guard; + using MutexAutoLock = std::unique_lock; + using RecursiveMutexAutoLock = std::unique_lock; #else #include "threading/mutex.h" @@ -44,6 +45,15 @@ private: Mutex &mutex; }; +class RecursiveMutexAutoLock +{ +public: + RecursiveMutexAutoLock(RecursiveMutex &m) : mutex(m) { mutex.lock(); } + ~RecursiveMutexAutoLock() { mutex.unlock(); } + +private: + RecursiveMutex &mutex; +}; #endif #endif From 52eea799285998d9d9595945f89c27a0be64b090 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Thu, 21 Jan 2016 16:04:41 +0100 Subject: [PATCH 50/68] Fix texture tear issue --- src/client/clientlauncher.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index be6426627..357d98b4d 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -544,6 +544,7 @@ bool ClientLauncher::create_engine_device() params.Vsync = vsync; params.EventReceiver = receiver; params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); + params.ZBufferBits = 24; #ifdef __ANDROID__ params.PrivateData = porting::app_global; params.OGLES2ShaderPath = std::string(porting::path_user + DIR_DELIM + From ef779b0ab6d7460fe074d8b2eda05864c822d905 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 23 Jan 2016 06:26:58 +0100 Subject: [PATCH 51/68] Fix compilation warning if compiling for android with c++11 --- build/android/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/android/Makefile b/build/android/Makefile index 50164d95f..64a50330a 100644 --- a/build/android/Makefile +++ b/build/android/Makefile @@ -849,8 +849,8 @@ $(ROOT)/jni/src/android_version.h : prep_srcdir echo "#define VERSION_MAJOR ${VERSION_MAJOR}"; \ echo "#define VERSION_MINOR ${VERSION_MINOR}"; \ echo "#define VERSION_PATCH ${VERSION_PATCH}"; \ - echo "#define VERSION_STRING STR(VERSION_MAJOR)\".\"STR(VERSION_MINOR)\ - \".\"STR(VERSION_PATCH)"; \ + echo "#define VERSION_STRING STR(VERSION_MAJOR) \".\" STR(VERSION_MINOR) \ + \".\" STR(VERSION_PATCH)"; \ echo "#endif"; \ } > $${VERSION_FILE_NEW}; \ if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \ From 735e3b70596e16d04de1edcd878deec3c539c6ed Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Jan 2016 14:40:24 -0800 Subject: [PATCH 52/68] Backface culling: Ignore setting in tiledef from old servers. Outdated servers are always sending tiledefs with culling enabled no matter what, as the value was previously entirely ignored. To compensate, we must (1) detect that we're running against an old server with a new client, and (2) disable culling for mesh, plantlike, firelike and liquid draw types no matter what the server is telling us. In order to achieve this, we need to bump the protocol version since we cannot rely on the tiledef version, and test for it being older. I've bumped the protocol version, although that should have likely happened in the actual change that introduced the new backface_culling PR #3578. Fortunately that's only 2 commits back at this point. We also explicitly test for the drawtype to assure we are not changing the culling value for other nodes, where it should remain enabled. This was tested against various pub servers, including 0.4.13 and 0.4.12. Fixes #3598 --- src/network/networkprotocol.h | 5 ++++- src/nodedef.cpp | 34 ++++++++++++++++++++++++++-------- src/nodedef.h | 2 +- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 674c68104..dc15326d9 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -132,9 +132,12 @@ with this program; if not, write to the Free Software Foundation, Inc., Rename GENERIC_CMD_SET_ATTACHMENT to GENERIC_CMD_ATTACH_TO PROTOCOL_VERSION 26: Add TileDef tileable_horizontal, tileable_vertical flags + PROTOCOL_VERSION 27: + backface_culling: backwards compatibility for playing with + newer client on pre-27 servers. */ -#define LATEST_PROTOCOL_VERSION 26 +#define LATEST_PROTOCOL_VERSION 27 // Server's supported network protocol range #define SERVER_PROTOCOL_VERSION_MIN 13 diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 0bcc00e47..e30cf6f12 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -139,7 +139,7 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const } } -void TileDef::deSerialize(std::istream &is) +void TileDef::deSerialize(std::istream &is, bool culling_ignore) { int version = readU8(is); name = deSerializeString(is); @@ -153,6 +153,11 @@ void TileDef::deSerialize(std::istream &is) tileable_horizontal = readU8(is); tileable_vertical = readU8(is); } + // when connecting to old servers - do not use + // provided values here since culling needs to be + // disabled by default for these drawtypes + if (culling_ignore) + backface_culling = false; } @@ -339,15 +344,22 @@ void ContentFeatures::deSerialize(std::istream &is) groups[name] = value; } drawtype = (enum NodeDrawType)readU8(is); + + bool ignore_culling = ((version <= 26) && + ((drawtype == NDT_MESH) || + (drawtype == NDT_PLANTLIKE) || + (drawtype == NDT_FIRELIKE) || + (drawtype == NDT_LIQUID))); + visual_scale = readF1000(is); if(readU8(is) != 6) throw SerializationError("unsupported tile count"); for(u32 i = 0; i < 6; i++) - tiledef[i].deSerialize(is); + tiledef[i].deSerialize(is, ignore_culling); if(readU8(is) != CF_SPECIAL_COUNT) throw SerializationError("unsupported CF_SPECIAL_COUNT"); for(u32 i = 0; i < CF_SPECIAL_COUNT; i++) - tiledef_special[i].deSerialize(is); + tiledef_special[i].deSerialize(is, ignore_culling); alpha = readU8(is); post_effect_color.setAlpha(readU8(is)); post_effect_color.setRed(readU8(is)); @@ -1258,7 +1270,6 @@ void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version) const "Unsupported version requested"); } - void ContentFeatures::deSerializeOld(std::istream &is, int version) { if (version == 5) // In PROTOCOL_VERSION 13 @@ -1272,15 +1283,22 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version) groups[name] = value; } drawtype = (enum NodeDrawType)readU8(is); + + bool ignore_culling = ((version <= 26) && + ((drawtype == NDT_MESH) || + (drawtype == NDT_PLANTLIKE) || + (drawtype == NDT_FIRELIKE) || + (drawtype == NDT_LIQUID))); + visual_scale = readF1000(is); if (readU8(is) != 6) throw SerializationError("unsupported tile count"); for (u32 i = 0; i < 6; i++) - tiledef[i].deSerialize(is); + tiledef[i].deSerialize(is, ignore_culling); if (readU8(is) != CF_SPECIAL_COUNT) throw SerializationError("unsupported CF_SPECIAL_COUNT"); for (u32 i = 0; i < CF_SPECIAL_COUNT; i++) - tiledef_special[i].deSerialize(is); + tiledef_special[i].deSerialize(is, ignore_culling); alpha = readU8(is); post_effect_color.setAlpha(readU8(is)); post_effect_color.setRed(readU8(is)); @@ -1324,12 +1342,12 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version) if (readU8(is) != 6) throw SerializationError("unsupported tile count"); for (u32 i = 0; i < 6; i++) - tiledef[i].deSerialize(is); + tiledef[i].deSerialize(is, drawtype); // CF_SPECIAL_COUNT in version 6 = 2 if (readU8(is) != 2) throw SerializationError("unsupported CF_SPECIAL_COUNT"); for (u32 i = 0; i < 2; i++) - tiledef_special[i].deSerialize(is); + tiledef_special[i].deSerialize(is, drawtype); alpha = readU8(is); post_effect_color.setAlpha(readU8(is)); post_effect_color.setRed(readU8(is)); diff --git a/src/nodedef.h b/src/nodedef.h index 8f4942c04..182bd09b2 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -137,7 +137,7 @@ struct TileDef } void serialize(std::ostream &os, u16 protocol_version) const; - void deSerialize(std::istream &is); + void deSerialize(std::istream &is, bool culling_ignore); }; enum NodeDrawType From a594963a7dad2f1ea3d4904610033164983a1389 Mon Sep 17 00:00:00 2001 From: Diego Martinez Date: Mon, 7 Dec 2015 00:49:01 -0300 Subject: [PATCH 53/68] Fix world config menu ignoring `name` in `mod.conf`. --- builtin/mainmenu/modmgr.lua | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/builtin/mainmenu/modmgr.lua b/builtin/mainmenu/modmgr.lua index 89292ed52..41e747b33 100644 --- a/builtin/mainmenu/modmgr.lua +++ b/builtin/mainmenu/modmgr.lua @@ -19,29 +19,29 @@ function get_mods(path,retval,modpack) local mods = core.get_dir_list(path, true) - for i=1, #mods, 1 do - if mods[i]:sub(1,1) ~= "." then + for _, name in ipairs(mods) do + if name:sub(1, 1) ~= "." then + local prefix = path .. DIR_DELIM .. name .. DIR_DELIM local toadd = {} - local modpackfile = nil + table.insert(retval, toadd) - toadd.name = mods[i] - toadd.path = path .. DIR_DELIM .. mods[i] .. DIR_DELIM - if modpack ~= nil and - modpack ~= "" then - toadd.modpack = modpack - else - local filename = path .. DIR_DELIM .. mods[i] .. DIR_DELIM .. "modpack.txt" - local error = nil - modpackfile,error = io.open(filename,"r") + local mod_conf = Settings(prefix .. "mod.conf"):to_table() + if mod_conf.name then + name = mod_conf.name end - if modpackfile ~= nil then - modpackfile:close() - toadd.is_modpack = true - table.insert(retval,toadd) - get_mods(path .. DIR_DELIM .. mods[i],retval,mods[i]) + toadd.name = name + toadd.path = prefix + + if modpack ~= nil and modpack ~= "" then + toadd.modpack = modpack else - table.insert(retval,toadd) + local modpackfile = io.open(prefix .. "modpack.txt") + if modpackfile then + modpackfile:close() + toadd.is_modpack = true + get_mods(prefix, retval, name) + end end end end From 73838a982ffa5882dc993d56df949a74cc0007cd Mon Sep 17 00:00:00 2001 From: Jun Zhang Date: Wed, 30 Dec 2015 16:01:36 +0100 Subject: [PATCH 54/68] Translated using Weblate (Chinese (China)) Currently translated at 34.8% (274 of 787 strings) --- po/zh_CN/minetest.po | 136 ++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 74 deletions(-) diff --git a/po/zh_CN/minetest.po b/po/zh_CN/minetest.po index c13b33049..52d850a32 100644 --- a/po/zh_CN/minetest.po +++ b/po/zh_CN/minetest.po @@ -8,10 +8,10 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-11-07 08:04+0000\n" +"PO-Revision-Date: 2015-12-30 16:01+0000\n" "Last-Translator: Jun Zhang \n" -"Language-Team: Chinese (China) \n" +"Language-Team: Chinese (China) " +"\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -21,14 +21,13 @@ msgstr "" #: builtin/fstk/ui.lua msgid "An error occured in a Lua script, such as a mod:" -msgstr "" +msgstr "Lua 脚本错误:" #: builtin/fstk/ui.lua msgid "An error occured:" msgstr "错误:" #: builtin/fstk/ui.lua -#, fuzzy msgid "Main menu" msgstr "主菜单" @@ -167,7 +166,7 @@ msgstr "世界名称" #: builtin/mainmenu/dlg_create_world.lua msgid "You have no subgames installed." -msgstr "你没有安装任何游戏" +msgstr "你没有安装任何游戏." #: builtin/mainmenu/dlg_delete_mod.lua msgid "Are you sure you want to delete \"$1\"?" @@ -254,9 +253,8 @@ msgid "Search" msgstr "搜索" #: builtin/mainmenu/store.lua -#, fuzzy msgid "Shortname:" -msgstr "短名称" +msgstr "短名称:" #: builtin/mainmenu/store.lua msgid "Successfully installed:" @@ -287,9 +285,8 @@ msgid "Previous Contributors" msgstr "前贡献者" #: builtin/mainmenu/tab_credits.lua -#, fuzzy msgid "Previous Core Developers" -msgstr "内部开发人员" +msgstr "前核心开发人员" #: builtin/mainmenu/tab_mods.lua msgid "Installed Mods:" @@ -324,9 +321,8 @@ msgid "Uninstall selected modpack" msgstr "删除选中的MOD包" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Address / Port :" -msgstr "地址/端口" +msgstr "地址/端口:" #: builtin/mainmenu/tab_multiplayer.lua src/settings_translation_file.cpp msgid "Client" @@ -337,14 +333,12 @@ msgid "Connect" msgstr "连接" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Creative mode" msgstr "创造模式" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Damage enabled" -msgstr "启用" +msgstr "启用伤害" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_server.lua #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp @@ -352,18 +346,16 @@ msgid "Delete" msgstr "删除" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Name / Password :" -msgstr "名字/密码" +msgstr "用户名/密码:" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Public Serverlist" msgstr "公共服务器列表" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "PvP enabled" -msgstr "启用" +msgstr "启用 PvP" #: builtin/mainmenu/tab_server.lua msgid "Bind Address" @@ -392,9 +384,8 @@ msgid "New" msgstr "新建" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua -#, fuzzy msgid "No world created or selected!" -msgstr "未给定世界名或未选择游戏" +msgstr "未创建或选择世界!" #: builtin/mainmenu/tab_server.lua msgid "Port" @@ -422,7 +413,7 @@ msgstr "启动游戏" #: builtin/mainmenu/tab_settings.lua msgid "\"$1\" is not a valid flag." -msgstr "" +msgstr "\"$1\" 不是合法的 flag." #: builtin/mainmenu/tab_settings.lua msgid "(No description of setting given)" @@ -437,28 +428,28 @@ msgid "Change keys" msgstr "改变键位设置" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Disabled" -msgstr "禁用MOD包" +msgstr "已禁用" #: builtin/mainmenu/tab_settings.lua msgid "Edit" msgstr "设置" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Enabled" -msgstr "启用" +msgstr "已启用" #: builtin/mainmenu/tab_settings.lua msgid "Format is 3 numbers separated by commas and inside brackets." -msgstr "" +msgstr "格式: (X, Y, Z)." #: builtin/mainmenu/tab_settings.lua msgid "" "Format: , , (, , ), , " ", " msgstr "" +"格式: , , (, , ), , , " +"" #: builtin/mainmenu/tab_settings.lua msgid "Games" @@ -470,28 +461,27 @@ msgstr "" #: builtin/mainmenu/tab_settings.lua msgid "Please enter a comma seperated list of flags." -msgstr "" +msgstr "请输入 flag, 多个 flag 以半角逗号分隔." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid integer." -msgstr "" +msgstr "请输入一个整数类型." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid number." -msgstr "" +msgstr "请输入一个合法的数字." #: builtin/mainmenu/tab_settings.lua msgid "Possible values are: " -msgstr "" +msgstr "可设置的 flag: " #: builtin/mainmenu/tab_settings.lua msgid "Restore Default" -msgstr "" +msgstr "回复初始设置" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Select path" -msgstr "选择" +msgstr "选择路径" #: builtin/mainmenu/tab_settings.lua msgid "Settings" @@ -499,20 +489,19 @@ msgstr "设置" #: builtin/mainmenu/tab_settings.lua msgid "Show technical names" -msgstr "" +msgstr "显示高级设置" #: builtin/mainmenu/tab_settings.lua msgid "The value must be greater than $1." -msgstr "" +msgstr "这个值必须大于 $1." #: builtin/mainmenu/tab_settings.lua msgid "The value must be lower than $1." -msgstr "" +msgstr "这个值必须小于 $1." #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Config mods" -msgstr "配置MOD" +msgstr "配置 MOD" #: builtin/mainmenu/tab_simple_main.lua #, fuzzy @@ -520,7 +509,6 @@ msgid "Main" msgstr "主菜单" #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Start Singleplayer" msgstr "单人游戏" @@ -538,47 +526,43 @@ msgstr "无资料可得" #: builtin/mainmenu/tab_texturepacks.lua msgid "None" -msgstr "" +msgstr "无" #: builtin/mainmenu/tab_texturepacks.lua msgid "Select texture pack:" msgstr "选择材质包:" #: builtin/mainmenu/tab_texturepacks.lua -#, fuzzy msgid "Texturepacks" msgstr "材质包" #: src/client.cpp -#, fuzzy msgid "Connection timed out." -msgstr "连接出错(超时?)" +msgstr "连接超时." #: src/client.cpp msgid "Done!" -msgstr "" +msgstr "完成!" #: src/client.cpp msgid "Initializing nodes" -msgstr "" +msgstr "初始化节点中" #: src/client.cpp msgid "Initializing nodes..." -msgstr "" +msgstr "初始化节点..." #: src/client.cpp msgid "Item textures..." msgstr "物品材质..." #: src/client.cpp -#, fuzzy msgid "Loading textures..." -msgstr "载入中..." +msgstr "载入材质..." #: src/client.cpp -#, fuzzy msgid "Rebuilding shaders..." -msgstr "正在解析地址..." +msgstr "重建渲染器..." #: src/client/clientlauncher.cpp msgid "Connection error (timed out?)" @@ -602,11 +586,11 @@ msgstr "没有选择世界或提供地址。未执行操作。" #: src/client/clientlauncher.cpp msgid "Player name too long." -msgstr "玩家的名字太长了" +msgstr "玩家的名字太长了." #: src/client/clientlauncher.cpp msgid "Provided world path doesn't exist: " -msgstr "提供世界地址不存在" +msgstr "提供的世界路径不存在: " #: src/fontengine.cpp msgid "needs_fallback_font" @@ -621,9 +605,8 @@ msgstr "" "查看 debug.txt 以获得详细信息。" #: src/game.cpp -#, fuzzy msgid "Change Keys" -msgstr "改变键位设置" +msgstr "更改键位设置" #: src/game.cpp msgid "Change Password" @@ -642,9 +625,8 @@ msgid "Creating client..." msgstr "正在建立客户端..." #: src/game.cpp -#, fuzzy msgid "Creating server..." -msgstr "正在建立服务器...." +msgstr "建立服务器...." #: src/game.cpp msgid "" @@ -687,6 +669,18 @@ msgid "" "- 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" #: src/game.cpp msgid "Exit to Menu" @@ -702,7 +696,7 @@ msgstr "物品定义..." #: src/game.cpp msgid "KiB/s" -msgstr "" +msgstr "KiB/s" #: src/game.cpp msgid "Media..." @@ -710,7 +704,7 @@ msgstr "媒体..." #: src/game.cpp msgid "MiB/s" -msgstr "" +msgstr "MiB/s" #: src/game.cpp msgid "Node definitions..." @@ -729,9 +723,8 @@ msgid "Respawn" msgstr "重生" #: src/game.cpp -#, fuzzy msgid "Shutting down..." -msgstr "关闭中......" +msgstr "关闭..." #: src/game.cpp msgid "Sound Volume" @@ -743,7 +736,7 @@ msgstr "你死了。" #: src/guiFormSpecMenu.cpp msgid "Enter " -msgstr "输入" +msgstr "输入 " #: src/guiFormSpecMenu.cpp msgid "ok" @@ -818,9 +811,8 @@ msgid "Sneak" msgstr "潜行" #: src/guiKeyChangeMenu.cpp -#, fuzzy msgid "Toggle Cinematic" -msgstr "切换快速移动模式" +msgstr "切换电影模式" #: src/guiKeyChangeMenu.cpp msgid "Toggle fast" @@ -1163,16 +1155,16 @@ msgid "" "0 = parallax occlusion with slope information (faster).\n" "1 = relief mapping (slower, more accurate)." msgstr "" +"0 = 利用梯度信息进行视差遮蔽 (较快).\n" +"1 = 浮雕映射 (较慢, 但准确)." #: src/settings_translation_file.cpp -#, fuzzy msgid "3D clouds" -msgstr "三维云彩" +msgstr "3D 云彩" #: src/settings_translation_file.cpp -#, fuzzy msgid "3D mode" -msgstr "飞行模式" +msgstr "3D 模式" #: src/settings_translation_file.cpp msgid "" @@ -1247,7 +1239,6 @@ msgid "Ambient occlusion gamma" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Anisotropic filtering" msgstr "各向异性过滤" @@ -1280,7 +1271,6 @@ msgid "Basic" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Bilinear filtering" msgstr "双线性过滤" @@ -1360,18 +1350,16 @@ msgid "Cloud radius" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Clouds" -msgstr "三维云彩" +msgstr "云彩" #: src/settings_translation_file.cpp msgid "Clouds are a client side effect." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Clouds in menu" -msgstr "主菜单" +msgstr "主菜单显示云彩" #: src/settings_translation_file.cpp msgid "Colored fog" From 1bd48e429849b43da3e14d199bde5d5f53726473 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Wed, 13 Jan 2016 09:23:08 +0100 Subject: [PATCH 55/68] Translated using Weblate (Danish) Currently translated at 30.1% (237 of 787 strings) --- po/da/minetest.po | 247 +++++++++++++++++++++------------------------- 1 file changed, 114 insertions(+), 133 deletions(-) diff --git a/po/da/minetest.po b/po/da/minetest.po index 5065541c6..ed3b0d66f 100644 --- a/po/da/minetest.po +++ b/po/da/minetest.po @@ -8,69 +8,70 @@ msgstr "" "Project-Id-Version: 0.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2013-02-17 00:41+0200\n" -"Last-Translator: Rune Biskopstö Christensen \n" -"Language-Team: \n" +"PO-Revision-Date: 2016-01-13 09:23+0000\n" +"Last-Translator: Peter Mikkelsen \n" +"Language-Team: Danish " +"\n" "Language: da\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: Weblate 1.4-dev\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 2.5-dev\n" #: builtin/fstk/ui.lua msgid "An error occured in a Lua script, such as a mod:" -msgstr "" +msgstr "Der skete en fejt i Lua scriptet, så som et mod:" #: builtin/fstk/ui.lua msgid "An error occured:" -msgstr "" +msgstr "Der skete en fejl:" #: builtin/fstk/ui.lua -#, fuzzy msgid "Main menu" msgstr "Hovedmenu" #: builtin/fstk/ui.lua builtin/mainmenu/store.lua msgid "Ok" -msgstr "" +msgstr "Ok" #: builtin/fstk/ui.lua -#, fuzzy msgid "Reconnect" -msgstr "Forbind" +msgstr "Forbind igen" #: builtin/fstk/ui.lua msgid "The server has requested a reconnect:" -msgstr "" +msgstr "Serveren har anmodet om at forbinde igen:" #: builtin/mainmenu/common.lua src/game.cpp msgid "Loading..." -msgstr "" +msgstr "Indlæser..." #: builtin/mainmenu/common.lua msgid "Protocol version mismatch. " -msgstr "" +msgstr "Protokol versionerne matchede ikke. " #: builtin/mainmenu/common.lua msgid "Server enforces protocol version $1. " -msgstr "" +msgstr "Serveren kræver protokol version $1. " #: builtin/mainmenu/common.lua msgid "Server supports protocol versions between $1 and $2. " -msgstr "" +msgstr "Serveren understøtter protokol versioner mellem $1 og $2. " #: builtin/mainmenu/common.lua msgid "Try reenabling public serverlist and check your internet connection." msgstr "" +"Prøv at slå den offentlige serverliste fra og til, og tjek din internet " +"forbindelse." #: builtin/mainmenu/common.lua msgid "We only support protocol version $1." -msgstr "" +msgstr "Vi understøtter kun protokol version $1." #: builtin/mainmenu/common.lua msgid "We support protocol versions between version $1 and $2." -msgstr "" +msgstr "Vi understøtter protokol versioner mellem $1 og $2." #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_create_world.lua #: builtin/mainmenu/dlg_rename_modpack.lua builtin/mainmenu/tab_settings.lua @@ -79,22 +80,18 @@ msgid "Cancel" msgstr "Anuller" #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_mods.lua -#, fuzzy msgid "Depends:" -msgstr "afhænger af:" +msgstr "Afhænger af:" #: builtin/mainmenu/dlg_config_world.lua -#, fuzzy msgid "Disable MP" -msgstr "Deaktivér alle" +msgstr "Deaktivér MP" #: builtin/mainmenu/dlg_config_world.lua -#, fuzzy msgid "Enable MP" -msgstr "Aktivér alle" +msgstr "Aktivér MP" #: builtin/mainmenu/dlg_config_world.lua -#, fuzzy msgid "Enable all" msgstr "Aktivér alle" @@ -103,19 +100,20 @@ msgid "" "Failed to enable mod \"$1\" as it contains disallowed characters. Only " "chararacters [a-z0-9_] are allowed." msgstr "" +"Kunne ikke slå mod \"$1\" til, da den indeholder ugyldige tegn. Kun tegnene " +"[a-z0-9_] er tilladte." #: builtin/mainmenu/dlg_config_world.lua -#, fuzzy msgid "Hide Game" -msgstr "Spil" +msgstr "Skjul spil" #: builtin/mainmenu/dlg_config_world.lua msgid "Hide mp content" -msgstr "" +msgstr "Skjul mp indhold" #: builtin/mainmenu/dlg_config_world.lua msgid "Mod:" -msgstr "" +msgstr "Mod:" #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_settings.lua #: src/guiKeyChangeMenu.cpp @@ -123,18 +121,16 @@ msgid "Save" msgstr "Gem" #: builtin/mainmenu/dlg_config_world.lua -#, fuzzy msgid "World:" -msgstr "Vælg verden:" +msgstr "Verden:" #: builtin/mainmenu/dlg_config_world.lua msgid "enabled" msgstr "aktiveret" #: builtin/mainmenu/dlg_create_world.lua -#, fuzzy msgid "A world named \"$1\" already exists" -msgstr "Kan ikke skabe verden: en verden med dette navn eksisterer allerede" +msgstr "En verden med navnet \"$1\" eksisterer allerede" #: builtin/mainmenu/dlg_create_world.lua msgid "Create" @@ -142,11 +138,11 @@ msgstr "Skab" #: builtin/mainmenu/dlg_create_world.lua msgid "Download a subgame, such as minetest_game, from minetest.net" -msgstr "" +msgstr "Hent et subgame, så som minetest_game fra minetest.net" #: builtin/mainmenu/dlg_create_world.lua msgid "Download one from minetest.net" -msgstr "" +msgstr "Hent en fra minetest.net" #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp msgid "Game" @@ -154,7 +150,7 @@ msgstr "Spil" #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp msgid "Mapgen" -msgstr "" +msgstr "Mapgen" #: builtin/mainmenu/dlg_create_world.lua msgid "No worldname given or no game selected" @@ -166,7 +162,7 @@ msgstr "" #: builtin/mainmenu/dlg_create_world.lua msgid "Warning: The minimal development test is meant for developers." -msgstr "" +msgstr "Advarsel: Den minimale udvikings test er kun lavet for udviklerne." #: builtin/mainmenu/dlg_create_world.lua msgid "World name" @@ -174,32 +170,31 @@ msgstr "Verdens navn" #: builtin/mainmenu/dlg_create_world.lua msgid "You have no subgames installed." -msgstr "" +msgstr "Du har ikke installeret nogle subgames." #: builtin/mainmenu/dlg_delete_mod.lua msgid "Are you sure you want to delete \"$1\"?" -msgstr "" +msgstr "Er du sikker på du vil slette \"$1\"?" #: builtin/mainmenu/dlg_delete_mod.lua msgid "Modmgr: failed to delete \"$1\"" -msgstr "" +msgstr "Modmgr: Kunne ikke slette \"$1\"" #: builtin/mainmenu/dlg_delete_mod.lua msgid "Modmgr: invalid modpath \"$1\"" -msgstr "" +msgstr "Modmgr: ugyldig mod-sti \"$1\"" #: builtin/mainmenu/dlg_delete_mod.lua msgid "No of course not!" -msgstr "" +msgstr "Nej selvfølgelig ikke!" #: builtin/mainmenu/dlg_delete_mod.lua builtin/mainmenu/dlg_delete_world.lua msgid "Yes" msgstr "Ja" #: builtin/mainmenu/dlg_delete_world.lua -#, fuzzy msgid "Delete World \"$1\"?" -msgstr "Slet verden" +msgstr "Slet verden \"$1\"?" #: builtin/mainmenu/dlg_delete_world.lua msgid "No" @@ -211,79 +206,80 @@ msgstr "Accepter" #: builtin/mainmenu/dlg_rename_modpack.lua msgid "Rename Modpack:" -msgstr "" +msgstr "Omdøb Modpack:" #: builtin/mainmenu/modmgr.lua msgid "" "\n" "Install Mod: unsupported filetype \"$1\" or broken archive" msgstr "" +"\n" +"Installer Mod: filtypen \"$1\" er enten ikke understøttet, ellers er arkivet " +"korrupt" #: builtin/mainmenu/modmgr.lua -#, fuzzy msgid "Failed to install $1 to $2" -msgstr "Mislykkedes i at initialisere verden" +msgstr "Kunne ikke installere $1 til $2" #: builtin/mainmenu/modmgr.lua msgid "Install Mod: file: \"$1\"" -msgstr "" +msgstr "Installer Mod: Fil: \"$1\"" #: builtin/mainmenu/modmgr.lua msgid "Install Mod: unable to find real modname for: $1" -msgstr "" +msgstr "Installer Mod: kunne ikke finde det rigtige mod navn for: $1" #: builtin/mainmenu/modmgr.lua msgid "Install Mod: unable to find suitable foldername for modpack $1" -msgstr "" +msgstr "Installer Mod: kunne ikke finde passende mappe navn for modpack $1" #: builtin/mainmenu/store.lua msgid "Close store" -msgstr "" +msgstr "Luk marked" #: builtin/mainmenu/store.lua msgid "Downloading $1, please wait..." -msgstr "" +msgstr "Henter $1, vent venligst..." #: builtin/mainmenu/store.lua msgid "Install" -msgstr "" +msgstr "Installer" #: builtin/mainmenu/store.lua msgid "Page $1 of $2" -msgstr "" +msgstr "Side $1 af $2" #: builtin/mainmenu/store.lua msgid "Rating" -msgstr "" +msgstr "Bedømmelse" #: builtin/mainmenu/store.lua msgid "Search" -msgstr "" +msgstr "Søg" #: builtin/mainmenu/store.lua -#, fuzzy msgid "Shortname:" -msgstr "Verdens navn" +msgstr "Kort navn:" #: builtin/mainmenu/store.lua msgid "Successfully installed:" -msgstr "" +msgstr "Succesfuldt installeret:" #: builtin/mainmenu/store.lua msgid "Unsorted" -msgstr "" +msgstr "Usorteret" #: builtin/mainmenu/store.lua msgid "re-Install" -msgstr "" +msgstr "geninstaller" #: builtin/mainmenu/tab_credits.lua msgid "Active Contributors" -msgstr "" +msgstr "Aktive bidragere" #: builtin/mainmenu/tab_credits.lua msgid "Core Developers" -msgstr "" +msgstr "Hoved udviklere" #: builtin/mainmenu/tab_credits.lua msgid "Credits" @@ -291,67 +287,63 @@ msgstr "Skabt af" #: builtin/mainmenu/tab_credits.lua msgid "Previous Contributors" -msgstr "" +msgstr "Tidligere bidragere" #: builtin/mainmenu/tab_credits.lua msgid "Previous Core Developers" -msgstr "" +msgstr "Tidligere hoved udviklere" #: builtin/mainmenu/tab_mods.lua msgid "Installed Mods:" -msgstr "" +msgstr "Installerede mods:" #: builtin/mainmenu/tab_mods.lua msgid "Mod information:" -msgstr "" +msgstr "Information om mod:" #: builtin/mainmenu/tab_mods.lua builtin/mainmenu/tab_settings.lua msgid "Mods" -msgstr "" +msgstr "Mods" #: builtin/mainmenu/tab_mods.lua msgid "No mod description available" -msgstr "" +msgstr "Der er ikke nogen beskrivelse af tilgængelig af det valgte mod" #: builtin/mainmenu/tab_mods.lua msgid "Rename" -msgstr "" +msgstr "Omdøb" #: builtin/mainmenu/tab_mods.lua -#, fuzzy msgid "Select Mod File:" -msgstr "Vælg verden:" +msgstr "Vælg mod fil:" #: builtin/mainmenu/tab_mods.lua msgid "Uninstall selected mod" -msgstr "" +msgstr "Afinstaller det valgte mod" #: builtin/mainmenu/tab_mods.lua msgid "Uninstall selected modpack" -msgstr "" +msgstr "Afinstaller den valgte modpack" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Address / Port :" -msgstr "Adresse/port" +msgstr "Adresse/port:" #: builtin/mainmenu/tab_multiplayer.lua src/settings_translation_file.cpp msgid "Client" -msgstr "" +msgstr "Klient" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Connect" msgstr "Forbind" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Creative mode" msgstr "Kreativ tilstand" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Damage enabled" -msgstr "aktiveret" +msgstr "Skade aktiveret" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_server.lua #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp @@ -359,18 +351,16 @@ msgid "Delete" msgstr "Slet" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Name / Password :" -msgstr "Navn/kodeord" +msgstr "Navn/kodeord:" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Public Serverlist" -msgstr "" +msgstr "Offentlig serverliste" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "PvP enabled" -msgstr "aktiveret" +msgstr "Spiller mod spiller aktiveret" #: builtin/mainmenu/tab_server.lua msgid "Bind Address" @@ -407,9 +397,8 @@ msgid "Port" msgstr "" #: builtin/mainmenu/tab_server.lua -#, fuzzy msgid "Public" -msgstr "Vis offentlig" +msgstr "Offentlig" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua msgid "Select World:" @@ -417,24 +406,23 @@ msgstr "Vælg verden:" #: builtin/mainmenu/tab_server.lua msgid "Server" -msgstr "" +msgstr "Server" #: builtin/mainmenu/tab_server.lua msgid "Server Port" -msgstr "" +msgstr "Server port" #: builtin/mainmenu/tab_server.lua -#, fuzzy msgid "Start Game" msgstr "Start spil / Forbind" #: builtin/mainmenu/tab_settings.lua msgid "\"$1\" is not a valid flag." -msgstr "" +msgstr "\"$1\" er ikke en gyldig indstilling." #: builtin/mainmenu/tab_settings.lua msgid "(No description of setting given)" -msgstr "" +msgstr "(Der er ikke nogen beskrivelse af denne indstilling)" #: builtin/mainmenu/tab_settings.lua msgid "Browse" @@ -445,22 +433,20 @@ msgid "Change keys" msgstr "Skift bindinger" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Disabled" -msgstr "Deaktivér alle" +msgstr "Deaktiveret" #: builtin/mainmenu/tab_settings.lua msgid "Edit" -msgstr "" +msgstr "Rediger" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Enabled" msgstr "aktiveret" #: builtin/mainmenu/tab_settings.lua msgid "Format is 3 numbers separated by commas and inside brackets." -msgstr "" +msgstr "Formatet er 3 tal, adskilt af kommaer, og omgivet af parenteser." #: builtin/mainmenu/tab_settings.lua msgid "" @@ -469,7 +455,6 @@ msgid "" msgstr "" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Games" msgstr "Spil" @@ -479,28 +464,27 @@ msgstr "" #: builtin/mainmenu/tab_settings.lua msgid "Please enter a comma seperated list of flags." -msgstr "" +msgstr "Indtast venligst en liste af indstillinger som er adskilt med kommaer." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid integer." -msgstr "" +msgstr "Indtast venligst et gyldigt heltal." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid number." -msgstr "" +msgstr "Indtast venligt et gyldigt nummer." #: builtin/mainmenu/tab_settings.lua msgid "Possible values are: " -msgstr "" +msgstr "Mulige værdier er: " #: builtin/mainmenu/tab_settings.lua msgid "Restore Default" -msgstr "" +msgstr "Gendan standard" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Select path" -msgstr "Vælg" +msgstr "Vælg sti" #: builtin/mainmenu/tab_settings.lua msgid "Settings" @@ -508,71 +492,70 @@ msgstr "Indstillinger" #: builtin/mainmenu/tab_settings.lua msgid "Show technical names" -msgstr "" +msgstr "Vis tekniske navne" #: builtin/mainmenu/tab_settings.lua msgid "The value must be greater than $1." -msgstr "" +msgstr "Værdien skal være større end $1." #: builtin/mainmenu/tab_settings.lua msgid "The value must be lower than $1." -msgstr "" +msgstr "Værdien skal være mindre end $1." #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Config mods" -msgstr "Konfigurér" +msgstr "Konfigurér mods" #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Main" msgstr "Hovedmenu" #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Start Singleplayer" -msgstr "Enligspiller" +msgstr "Enlig spiller" #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp msgid "Play" -msgstr "Afspil" +msgstr "Spil" #: builtin/mainmenu/tab_singleplayer.lua msgid "Singleplayer" -msgstr "Enligspiller" +msgstr "Enlig spiller" #: builtin/mainmenu/tab_texturepacks.lua msgid "No information available" -msgstr "" +msgstr "Der er ikke nogen information tilgængelig" #: builtin/mainmenu/tab_texturepacks.lua +#, fuzzy msgid "None" -msgstr "" +msgstr "Ingen" #: builtin/mainmenu/tab_texturepacks.lua +#, fuzzy msgid "Select texture pack:" msgstr "" #: builtin/mainmenu/tab_texturepacks.lua +#, fuzzy msgid "Texturepacks" msgstr "" #: src/client.cpp -#, fuzzy msgid "Connection timed out." -msgstr "Forbindelses fejl (udløbelse af tidsfrist?)" +msgstr "Forbindelses fejl (tidsfristen udløb)." #: src/client.cpp msgid "Done!" -msgstr "" +msgstr "Færdig!" #: src/client.cpp msgid "Initializing nodes" -msgstr "" +msgstr "Initialiserer noder" #: src/client.cpp msgid "Initializing nodes..." -msgstr "" +msgstr "Initialiserer noder..." #: src/client.cpp msgid "Item textures..." @@ -604,11 +587,11 @@ msgstr "Hovedmenu" #: src/client/clientlauncher.cpp msgid "No world selected and no address provided. Nothing to do." -msgstr "Ingen verden valgt og ingen adresse angivet. Ingen opgave at lave." +msgstr "Ingen verden valgt og ingen adresse angivet. Der er ikke noget at gøre." #: src/client/clientlauncher.cpp msgid "Player name too long." -msgstr "" +msgstr "Spillerens navn er for langt." #: src/client/clientlauncher.cpp msgid "Provided world path doesn't exist: " @@ -627,9 +610,8 @@ msgstr "" "Tjek debug.txt for detaljer." #: src/game.cpp -#, fuzzy msgid "Change Keys" -msgstr "Skift bindinger" +msgstr "Skift tastatur-bindinger" #: src/game.cpp msgid "Change Password" @@ -637,7 +619,7 @@ msgstr "Skift kodeord" #: src/game.cpp msgid "Connecting to server..." -msgstr "" +msgstr "Forbinder til server..." #: src/game.cpp msgid "Continue" @@ -700,7 +682,7 @@ msgstr "" #: src/game.cpp msgid "Media..." -msgstr "" +msgstr "Medier..." #: src/game.cpp msgid "MiB/s" @@ -724,11 +706,11 @@ msgstr "Genopstå" #: src/game.cpp msgid "Shutting down..." -msgstr "" +msgstr "Lukker ned..." #: src/game.cpp msgid "Sound Volume" -msgstr "" +msgstr "Lydniveau" #: src/game.cpp msgid "You died." @@ -740,7 +722,7 @@ msgstr "" #: src/guiFormSpecMenu.cpp msgid "ok" -msgstr "" +msgstr "ok" #: src/guiKeyChangeMenu.cpp msgid "\"Use\" = climb down" @@ -1358,9 +1340,8 @@ msgid "Cloud radius" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Clouds" -msgstr "3D skyer" +msgstr "Skyer" #: src/settings_translation_file.cpp msgid "Clouds are a client side effect." From d486ca064c7a357f273042e27364501a14128115 Mon Sep 17 00:00:00 2001 From: Rui Date: Wed, 13 Jan 2016 08:54:13 +0100 Subject: [PATCH 56/68] Translated using Weblate (Japanese) Currently translated at 42.0% (331 of 787 strings) --- po/ja/minetest.po | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/po/ja/minetest.po b/po/ja/minetest.po index fcd189d95..c819f72da 100644 --- a/po/ja/minetest.po +++ b/po/ja/minetest.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-12-19 11:07+0000\n" +"PO-Revision-Date: 2016-01-13 08:54+0000\n" "Last-Translator: Rui \n" "Language-Team: Japanese " "\n" @@ -134,7 +134,6 @@ msgid "Download a subgame, such as minetest_game, from minetest.net" msgstr "minetest.netからminetest_gameなどのサブゲームをダウンロードしてください" #: builtin/mainmenu/dlg_create_world.lua -#, fuzzy msgid "Download one from minetest.net" msgstr "minetest.netからダウンロードしてください" @@ -358,7 +357,6 @@ msgid "PvP enabled" msgstr "PvP有効" #: builtin/mainmenu/tab_server.lua -#, fuzzy msgid "Bind Address" msgstr "バインドアドレス" @@ -413,7 +411,6 @@ msgid "Start Game" msgstr "ゲームスタート" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "\"$1\" is not a valid flag." msgstr "\"$1\"は有効なフラグではありません。" @@ -442,9 +439,8 @@ msgid "Enabled" msgstr "有効" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Format is 3 numbers separated by commas and inside brackets." -msgstr "書式は、コンマとかっこで区切られた 3 つの数字です。" +msgstr "括弧内に3つの数字をカンマで区切って入力してください。" #: builtin/mainmenu/tab_settings.lua #, fuzzy @@ -460,14 +456,12 @@ msgid "Games" msgstr "ゲーム" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Optionally the lacunarity can be appended with a leading comma." -msgstr "空隙性随意大手カンマを付加することができます。" +msgstr "空隙性の値には、任意でカンマを付けて読みやすくすることができます。" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Please enter a comma seperated list of flags." -msgstr "フラグのリストはカンマで区切って入力してください。" +msgstr "フラグはカンマで区切られた一覧で入力してください。" #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid integer." @@ -478,27 +472,24 @@ msgid "Please enter a valid number." msgstr "有効な数字を入力してください。" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Possible values are: " -msgstr "可能な値: " +msgstr "使用可能な値: " #: builtin/mainmenu/tab_settings.lua msgid "Restore Default" msgstr "初期設定に戻す" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Select path" -msgstr "ファイルパスを選択" +msgstr "ファイルの場所を選択" #: builtin/mainmenu/tab_settings.lua msgid "Settings" msgstr "設定" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Show technical names" -msgstr "技術名称を表示" +msgstr "パラメータ名を表示" #: builtin/mainmenu/tab_settings.lua msgid "The value must be greater than $1." @@ -577,30 +568,26 @@ msgid "Connection error (timed out?)" msgstr "接続エラー (タイムアウト?)" #: src/client/clientlauncher.cpp -#, fuzzy msgid "Could not find or load game \"" -msgstr "以下のゲームの読み込みができません\"" +msgstr "以下のゲームが見つからないか読み込めません \"" #: src/client/clientlauncher.cpp -#, fuzzy msgid "Invalid gamespec." -msgstr "無効なgamespecです。" +msgstr "無効なゲーム情報です。" #: src/client/clientlauncher.cpp msgid "Main Menu" msgstr "メインメニュー" #: src/client/clientlauncher.cpp -#, fuzzy msgid "No world selected and no address provided. Nothing to do." -msgstr "ワールドが選択されていないアドレスです。続行できません。" +msgstr "ワールドが選択されていないか存在しないアドレスです。続行できません。" #: src/client/clientlauncher.cpp msgid "Player name too long." msgstr "プレイヤー名が長過ぎます。" #: src/client/clientlauncher.cpp -#, fuzzy msgid "Provided world path doesn't exist: " msgstr "ワールドが存在しません: " @@ -667,7 +654,6 @@ msgstr "" "- T: チャット\n" #: src/game.cpp -#, fuzzy msgid "" "Default Controls:\n" "No menu visible:\n" @@ -685,9 +671,9 @@ msgstr "" "デフォルトの操作:\n" "タッチ操作:\n" "- シングルタップ: ブロックの破壊\n" -"- ダブルタップ: 設置、使用\n" +"- ダブルタップ: 設置/使用\n" "- スライド: 見回す\n" -"メニュー、インベントリの操作:\n" +"メニュー/インベントリの操作:\n" "- メニューの外をダブルタップ:\n" " --> 閉じる\n" "- アイテムをタッチ:\n" @@ -1168,6 +1154,8 @@ msgid "" "0 = parallax occlusion with slope information (faster).\n" "1 = relief mapping (slower, more accurate)." msgstr "" +"0 = 斜面情報付きの視差遮蔽マッピング(高速)。\n" +"1 = リリーフマッピング(正確だが低速)。" #: src/settings_translation_file.cpp msgid "3D clouds" @@ -1178,7 +1166,6 @@ msgid "3D mode" msgstr "3Dモード" #: src/settings_translation_file.cpp -#, fuzzy msgid "" "3D support.\n" "Currently supported:\n" @@ -1189,9 +1176,9 @@ msgid "" "- sidebyside: split screen side by side." msgstr "" "3Dサポート\n" -"現在サポートしている:\n" -"- none: 3D出力なし\n" -"- anaglyph: cyan/magenta color 3d.\n" +"サポートしている出力:\n" +"- none: 3D出力なし。\n" +"- anaglyph: 赤/青の色による3D。\n" "- interlaced: odd/even line based polarisation screen support.\n" "- topbottom: split screen top/bottom.\n" "- sidebyside: split screen side by side." From 42dc568f16a7bc93a34f55113df33ba090959817 Mon Sep 17 00:00:00 2001 From: Rui Date: Thu, 14 Jan 2016 08:53:58 +0100 Subject: [PATCH 57/68] Translated using Weblate (Japanese) Currently translated at 43.4% (342 of 787 strings) --- po/ja/minetest.po | 61 ++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/po/ja/minetest.po b/po/ja/minetest.po index c819f72da..e3d9eab7c 100644 --- a/po/ja/minetest.po +++ b/po/ja/minetest.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2016-01-13 08:54+0000\n" +"PO-Revision-Date: 2016-01-14 08:53+0000\n" "Last-Translator: Rui \n" "Language-Team: Japanese " "\n" @@ -1177,17 +1177,20 @@ msgid "" msgstr "" "3Dサポート\n" "サポートしている出力:\n" -"- none: 3D出力なし。\n" -"- anaglyph: 赤/青の色による3D。\n" -"- interlaced: odd/even line based polarisation screen support.\n" -"- topbottom: split screen top/bottom.\n" -"- sidebyside: split screen side by side." +"- none: 3D出力を行いません。\n" +"- anaglyph: 赤/青の色による3Dです。\n" +"- interlaced: 偶数/奇数のラインをベースで偏光式スクリーンに対応しています。\n" +"- topbottom: 画面を上下で分割します。\n" +"- sidebyside: 画面を左右で分割します。" #: src/settings_translation_file.cpp +#, fuzzy msgid "" "A chosen map seed for a new map, leave empty for random.\n" "Will be overridden when creating a new world in the main menu." msgstr "" +"新規マップを作成する際の初期シード値です。空にするとランダムに設定されます。\n" +"メインメニューから新規ワールドを作成する際に上書きされることがあります。" #: src/settings_translation_file.cpp msgid "A message to be displayed to all clients when the server crashes." @@ -1198,8 +1201,9 @@ msgid "A message to be displayed to all clients when the server shuts down." msgstr "サーバー終了時に全てのクライアントへ表示するメッセージ。" #: src/settings_translation_file.cpp +#, fuzzy msgid "Absolute limit of emerge queues" -msgstr "" +msgstr "エマージキューの絶対的な制限値" #: src/settings_translation_file.cpp #, fuzzy @@ -3535,7 +3539,6 @@ msgid "Waving leaves" msgstr "揺れる葉" #: src/settings_translation_file.cpp -#, fuzzy msgid "Waving plants" msgstr "揺れる草花" @@ -3544,19 +3547,16 @@ msgid "Waving water" msgstr "揺れる水" #: src/settings_translation_file.cpp -#, fuzzy msgid "Waving water height" -msgstr "揺れる水" +msgstr "水が揺れる高さ" #: src/settings_translation_file.cpp -#, fuzzy msgid "Waving water length" -msgstr "揺れる水" +msgstr "水が揺れる丈" #: src/settings_translation_file.cpp -#, fuzzy msgid "Waving water speed" -msgstr "揺れる水" +msgstr "水が揺れる速度" #: src/settings_translation_file.cpp msgid "" @@ -3585,6 +3585,7 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp +#, fuzzy msgid "" "Where the map generator stops.\n" "Please note:\n" @@ -3593,58 +3594,74 @@ msgid "" "- Those groups have an offset of -32, -32 nodes from the origin.\n" "- Only groups which are within the map_generation_limit are generated" msgstr "" +"どこでマップ生成を停止するかの設定です。\n" +"注意:\n" +"- 最大で31000です(これ以上に設定しても効果はありません)。\n" +"- マップ生成は80x80x80ノードのグループで動作します (5x5x5マップブロック)。\n" +"- このグループは原点から-32、-32ノードのオフセットがあります。\n" +"- グループはmap_generation_limit内で生成されたものに限ります。" #: src/settings_translation_file.cpp msgid "" "Whether freetype fonts are used, requires freetype support to be compiled in." -msgstr "" +msgstr "Freetypeフォントを利用するかどうかの設定です。Freetypeをサポートするビルドである必要があります。" #: src/settings_translation_file.cpp +#, fuzzy msgid "Whether node texture animations should be desynchronized per mapblock." -msgstr "" +msgstr "ノードのテクスチャのアニメーションをマップブロックごとに非同期にするかどうかの設定です。" #: src/settings_translation_file.cpp msgid "" "Whether players are shown to clients without any range limit.\n" "Deprecated, use the setting player_transfer_distance instead." msgstr "" +"視界の範囲に関わらずクライアントにプレイヤーを表示するかどうかの設定です。\n" +"非推奨です。player_transfer_distance instead設定を利用してください。" #: src/settings_translation_file.cpp msgid "Whether to allow players to damage and kill each other." -msgstr "" +msgstr "他のプレイヤーを殺すことができるかどうかの設定です。" #: src/settings_translation_file.cpp msgid "" "Whether to ask clients to reconnect after a (Lua) crash.\n" "Set this to true if your server is set up to restart automatically." msgstr "" +"(Luaが)クラッシュした際にクライアントに再接続を要求するかどうかの設定です。\n" +"サーバーが自動で再起動されるように設定されているならばtrueに設定してください。" #: src/settings_translation_file.cpp msgid "Whether to fog out the end of the visible area." -msgstr "" +msgstr "可視領域の端に霧を表示するかどうかの設定です。" #: src/settings_translation_file.cpp msgid "" "Whether to show the client debug info (has the same effect as hitting F5)." -msgstr "" +msgstr "クライアントのデバッグ情報を表示するかどうかの設定です(F5を押すのと同じ効果)。" #: src/settings_translation_file.cpp msgid "Width of the selectionbox's lines around nodes." -msgstr "" +msgstr "ノードを選択した際に表示される線の幅です。" #: src/settings_translation_file.cpp +#, fuzzy msgid "" "World directory (everything in the world is stored here).\n" "Not needed if starting from the main menu." msgstr "" +"ワールドを保存するディレクトリです(全てのワールドはここに保存されます)。\n" +"メインメニューから開始する場合必要ありません。" #: src/settings_translation_file.cpp +#, fuzzy msgid "cURL file download timeout" -msgstr "" +msgstr "cURLファイルダウンロードタイムアウト" #: src/settings_translation_file.cpp +#, fuzzy msgid "cURL parallel limit" -msgstr "" +msgstr "cURLパラレル制限" #: src/settings_translation_file.cpp msgid "cURL timeout" From e3e75a43db65e358725f2a9012f0b823050f2d29 Mon Sep 17 00:00:00 2001 From: Ian giestas pauli Date: Thu, 14 Jan 2016 18:20:14 +0100 Subject: [PATCH 58/68] Translated using Weblate (Portuguese) Currently translated at 23.6% (186 of 787 strings) --- po/pt/minetest.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/po/pt/minetest.po b/po/pt/minetest.po index da85b92d7..646821ae7 100644 --- a/po/pt/minetest.po +++ b/po/pt/minetest.po @@ -8,15 +8,16 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2014-01-06 01:45+0200\n" -"Last-Translator: João Farias \n" -"Language-Team: LANGUAGE \n" +"PO-Revision-Date: 2016-01-14 18:20+0000\n" +"Last-Translator: Ian giestas pauli \n" +"Language-Team: Portuguese " +"\n" "Language: pt\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: Weblate 1.7-dev\n" +"X-Generator: Weblate 2.5-dev\n" #: builtin/fstk/ui.lua msgid "An error occured in a Lua script, such as a mod:" @@ -36,13 +37,12 @@ msgid "Ok" msgstr "Ok" #: builtin/fstk/ui.lua -#, fuzzy msgid "Reconnect" -msgstr "Ligar" +msgstr "Reconectar" #: builtin/fstk/ui.lua msgid "The server has requested a reconnect:" -msgstr "" +msgstr "O servidor requisitou uma reconexão:" #: builtin/mainmenu/common.lua src/game.cpp msgid "Loading..." From e24de58b4d14396eda1755b498f2d997c3e87131 Mon Sep 17 00:00:00 2001 From: Ian giestas pauli Date: Thu, 14 Jan 2016 18:32:23 +0100 Subject: [PATCH 59/68] Translated using Weblate (Portuguese (Brazil)) Currently translated at 26.6% (210 of 787 strings) --- po/pt_BR/minetest.po | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/po/pt_BR/minetest.po b/po/pt_BR/minetest.po index 7b2029c0c..e4b52146f 100644 --- a/po/pt_BR/minetest.po +++ b/po/pt_BR/minetest.po @@ -8,20 +8,20 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-10-27 16:46+0200\n" -"Last-Translator: PilzAdam \n" -"Language-Team: Portuguese (Brazil) \n" +"PO-Revision-Date: 2016-01-14 18:32+0000\n" +"Last-Translator: Ian giestas pauli \n" +"Language-Team: Portuguese (Brazil) " +"\n" "Language: pt_BR\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" +"Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 2.5-dev\n" #: builtin/fstk/ui.lua msgid "An error occured in a Lua script, such as a mod:" -msgstr "Ocorreu um erro no script Lua, como um mod:" +msgstr "Ocorreu um erro no script Lua, assim como em um mod:" #: builtin/fstk/ui.lua msgid "An error occured:" @@ -36,13 +36,12 @@ msgid "Ok" msgstr "Ok" #: builtin/fstk/ui.lua -#, fuzzy msgid "Reconnect" -msgstr "Conectar" +msgstr "Reconectar" #: builtin/fstk/ui.lua msgid "The server has requested a reconnect:" -msgstr "" +msgstr "O servidor requisitou uma reconexão:" #: builtin/mainmenu/common.lua src/game.cpp msgid "Loading..." @@ -50,27 +49,29 @@ msgstr "Carregando..." #: builtin/mainmenu/common.lua msgid "Protocol version mismatch. " -msgstr "" +msgstr "Versão do protocolo incompatível. " #: builtin/mainmenu/common.lua msgid "Server enforces protocol version $1. " -msgstr "" +msgstr "O servidor suporta o protocolo versão $1. " #: builtin/mainmenu/common.lua msgid "Server supports protocol versions between $1 and $2. " -msgstr "" +msgstr "O servidor suporta entre as versões $1 e $2 do protocolo. " #: builtin/mainmenu/common.lua msgid "Try reenabling public serverlist and check your internet connection." msgstr "" +"Tente reabilitar a lista de servidores publicos e checar sua conexão de " +"internet." #: builtin/mainmenu/common.lua msgid "We only support protocol version $1." -msgstr "" +msgstr "Nós apenas suportamos a versão $1 do protocolo." #: builtin/mainmenu/common.lua msgid "We support protocol versions between version $1 and $2." -msgstr "" +msgstr "Nós suportamos entre as versões $1 e $2 do protocolo." #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_create_world.lua #: builtin/mainmenu/dlg_rename_modpack.lua builtin/mainmenu/tab_settings.lua @@ -99,6 +100,9 @@ msgid "" "Failed to enable mod \"$1\" as it contains disallowed characters. Only " "chararacters [a-z0-9_] are allowed." msgstr "" +"Falha ao carregar mod \"$1\" devido ao fato de seu nome possuir caracteres " +"inválidos. Apenas caracteres de \"a\" até \"z\" e algarísmos de 0 até 9 são " +"permitidos." #: builtin/mainmenu/dlg_config_world.lua msgid "Hide Game" @@ -135,11 +139,11 @@ msgstr "Criar" #: builtin/mainmenu/dlg_create_world.lua msgid "Download a subgame, such as minetest_game, from minetest.net" -msgstr "" +msgstr "Baixe um subgame, como o minetest_game, do site minetest.net" #: builtin/mainmenu/dlg_create_world.lua msgid "Download one from minetest.net" -msgstr "" +msgstr "Baixe um do site minetest.net" #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp msgid "Game" From d0d7122c002bddcd782410ea7eee03e02ed00493 Mon Sep 17 00:00:00 2001 From: Ian giestas pauli Date: Thu, 14 Jan 2016 20:25:46 +0100 Subject: [PATCH 60/68] Translated using Weblate (Portuguese (Brazil)) Currently translated at 41.6% (328 of 787 strings) --- po/pt_BR/minetest.po | 312 +++++++++++++++++++++++-------------------- 1 file changed, 170 insertions(+), 142 deletions(-) diff --git a/po/pt_BR/minetest.po b/po/pt_BR/minetest.po index e4b52146f..4728e7efd 100644 --- a/po/pt_BR/minetest.po +++ b/po/pt_BR/minetest.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2016-01-14 18:32+0000\n" +"PO-Revision-Date: 2016-01-14 20:25+0000\n" "Last-Translator: Ian giestas pauli \n" "Language-Team: Portuguese (Brazil) " "\n" @@ -165,6 +165,7 @@ msgstr "Seed" #: builtin/mainmenu/dlg_create_world.lua msgid "Warning: The minimal development test is meant for developers." msgstr "" +"Aviso: O game \"minimal development test\" apenas serve para desenvolvedores." #: builtin/mainmenu/dlg_create_world.lua msgid "World name" @@ -172,7 +173,7 @@ msgstr "Nome do mundo" #: builtin/mainmenu/dlg_create_world.lua msgid "You have no subgames installed." -msgstr "" +msgstr "Você não possui nenhum subgame instalado." #: builtin/mainmenu/dlg_delete_mod.lua msgid "Are you sure you want to delete \"$1\"?" @@ -211,13 +212,13 @@ msgid "Rename Modpack:" msgstr "Renomear pacote de módulos:" #: builtin/mainmenu/modmgr.lua -#, fuzzy msgid "" "\n" "Install Mod: unsupported filetype \"$1\" or broken archive" msgstr "" "\n" -"Instalação de módulo: o tipo de arquivo \"$1\" não é suportado" +"Instalação de módulo: o tipo de arquivo \"$1\" não é suportado ou o arquivo " +"está corrompido" #: builtin/mainmenu/modmgr.lua msgid "Failed to install $1 to $2" @@ -240,11 +241,11 @@ msgstr "" #: builtin/mainmenu/store.lua msgid "Close store" -msgstr "" +msgstr "Fechar Mod Store" #: builtin/mainmenu/store.lua msgid "Downloading $1, please wait..." -msgstr "" +msgstr "Baixando $1, por favor aguarde..." #: builtin/mainmenu/store.lua msgid "Install" @@ -260,20 +261,19 @@ msgstr "Classificação" #: builtin/mainmenu/store.lua msgid "Search" -msgstr "" +msgstr "Procurar" #: builtin/mainmenu/store.lua -#, fuzzy msgid "Shortname:" -msgstr "Nome do mundo" +msgstr "Nome curto:" #: builtin/mainmenu/store.lua msgid "Successfully installed:" -msgstr "" +msgstr "Instalado com sucesso:" #: builtin/mainmenu/store.lua msgid "Unsorted" -msgstr "" +msgstr "Desorganizado" #: builtin/mainmenu/store.lua msgid "re-Install" @@ -296,9 +296,8 @@ msgid "Previous Contributors" msgstr "Colaboradores anteriores" #: builtin/mainmenu/tab_credits.lua -#, fuzzy msgid "Previous Core Developers" -msgstr "Desenvolvedores principais" +msgstr "Desenvolvedores principais anteriores" #: builtin/mainmenu/tab_mods.lua msgid "Installed Mods:" @@ -333,9 +332,8 @@ msgid "Uninstall selected modpack" msgstr "Desinstalar o pacote de módulos selecionado" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Address / Port :" -msgstr "Endereço/Porta" +msgstr "Endereço / Porta :" #: builtin/mainmenu/tab_multiplayer.lua src/settings_translation_file.cpp msgid "Client" @@ -346,14 +344,12 @@ msgid "Connect" msgstr "Conectar" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Creative mode" msgstr "Modo criativo" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Damage enabled" -msgstr "habilitado" +msgstr "Habilitar dano" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_server.lua #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp @@ -361,22 +357,20 @@ msgid "Delete" msgstr "Excluir" #: builtin/mainmenu/tab_multiplayer.lua -#, fuzzy msgid "Name / Password :" -msgstr "Nome/Senha" +msgstr "Nome / Senha :" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Public Serverlist" -msgstr "Servidores públicos" +msgstr "Lista de servidores públicos" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "PvP enabled" -msgstr "habilitado" +msgstr "PvP habilitado" #: builtin/mainmenu/tab_server.lua msgid "Bind Address" -msgstr "" +msgstr "Endereço de Bind" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua msgid "Configure" @@ -394,21 +388,19 @@ msgstr "Habilitar dano" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_simple_main.lua msgid "Name/Password" -msgstr "Nome/Senha" +msgstr "Nome / Senha" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua msgid "New" msgstr "Novo" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua -#, fuzzy msgid "No world created or selected!" -msgstr "" -"Não foi fornecido nenhum nome para o mundo ou não foi selecionado nenhum jogo" +msgstr "Nenhum mundo criado ou selecionado!" #: builtin/mainmenu/tab_server.lua msgid "Port" -msgstr "" +msgstr "Porta" #: builtin/mainmenu/tab_server.lua msgid "Public" @@ -432,43 +424,43 @@ msgstr "Iniciar o jogo" #: builtin/mainmenu/tab_settings.lua msgid "\"$1\" is not a valid flag." -msgstr "" +msgstr "\"$1\" não é uma flag válida." #: builtin/mainmenu/tab_settings.lua msgid "(No description of setting given)" -msgstr "" +msgstr "(Nenhuma descrição das configurações foi fornecida)" #: builtin/mainmenu/tab_settings.lua msgid "Browse" -msgstr "" +msgstr "Navegar" #: builtin/mainmenu/tab_settings.lua msgid "Change keys" msgstr "Mudar teclas" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Disabled" -msgstr "Desabilitar PMs" +msgstr "Desabilitado" #: builtin/mainmenu/tab_settings.lua msgid "Edit" -msgstr "" +msgstr "Editar" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Enabled" -msgstr "habilitado" +msgstr "Habilitado" #: builtin/mainmenu/tab_settings.lua msgid "Format is 3 numbers separated by commas and inside brackets." -msgstr "" +msgstr "O formato é de 3 números separados por virgulas e dentro de colchetes." #: builtin/mainmenu/tab_settings.lua msgid "" "Format: , , (, , ), , " ", " msgstr "" +"Formato: , , (, , ), , " +", " #: builtin/mainmenu/tab_settings.lua msgid "Games" @@ -477,31 +469,31 @@ msgstr "Jogos" #: builtin/mainmenu/tab_settings.lua msgid "Optionally the lacunarity can be appended with a leading comma." msgstr "" +"Opcionalmente essas lacunas podem ser colocados com a vírgula na frente." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a comma seperated list of flags." -msgstr "" +msgstr "Por favor, digite uma lista de flags separadas por vírgulas." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid integer." -msgstr "" +msgstr "Por favor entre com um inteiro válido." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid number." -msgstr "" +msgstr "Por favor entre com um número válido." #: builtin/mainmenu/tab_settings.lua msgid "Possible values are: " -msgstr "" +msgstr "Os possíveis valores são: " #: builtin/mainmenu/tab_settings.lua msgid "Restore Default" -msgstr "" +msgstr "Restaurar para o padrão" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Select path" -msgstr "Select" +msgstr "Selecionar diretório" #: builtin/mainmenu/tab_settings.lua msgid "Settings" @@ -509,20 +501,19 @@ msgstr "Configurações" #: builtin/mainmenu/tab_settings.lua msgid "Show technical names" -msgstr "" +msgstr "Mostrar nomes técnicos" #: builtin/mainmenu/tab_settings.lua msgid "The value must be greater than $1." -msgstr "" +msgstr "O valor deve ser maior que $1." #: builtin/mainmenu/tab_settings.lua msgid "The value must be lower than $1." -msgstr "" +msgstr "O valor deve ser menor que $1." #: builtin/mainmenu/tab_simple_main.lua -#, fuzzy msgid "Config mods" -msgstr "Configurar" +msgstr "Configurar Mods" #: builtin/mainmenu/tab_simple_main.lua #, fuzzy @@ -548,7 +539,7 @@ msgstr "Nenhuma informação disponível" #: builtin/mainmenu/tab_texturepacks.lua msgid "None" -msgstr "" +msgstr "Nenhum" #: builtin/mainmenu/tab_texturepacks.lua msgid "Select texture pack:" @@ -560,35 +551,32 @@ msgid "Texturepacks" msgstr "Pacotes de texturas" #: src/client.cpp -#, fuzzy msgid "Connection timed out." -msgstr "Erro de conexão (tempo excedido?)" +msgstr "Erro de conexão (tempo excedido)." #: src/client.cpp msgid "Done!" -msgstr "" +msgstr "Pronto!" #: src/client.cpp msgid "Initializing nodes" -msgstr "" +msgstr "Inicializando nodes" #: src/client.cpp msgid "Initializing nodes..." -msgstr "" +msgstr "Inicializando nodes..." #: src/client.cpp msgid "Item textures..." msgstr "Texturas dos itens..." #: src/client.cpp -#, fuzzy msgid "Loading textures..." -msgstr "Carregando..." +msgstr "Carregando texturas..." #: src/client.cpp -#, fuzzy msgid "Rebuilding shaders..." -msgstr "Resolvendo os endereços..." +msgstr "Recompilando shaders..." #: src/client/clientlauncher.cpp msgid "Connection error (timed out?)" @@ -609,20 +597,20 @@ msgstr "Menu principal" #: src/client/clientlauncher.cpp msgid "No world selected and no address provided. Nothing to do." msgstr "" -"Nenhum mundo foi selecionado e nenhum endereço fornecido. Não existe nada a " -"ser feito." +"Nenhum mundo foi selecionado e nenhum endereço fornecido. Nada a ser feito." #: src/client/clientlauncher.cpp msgid "Player name too long." -msgstr "" +msgstr "Seu nome de jogador é muito longo." #: src/client/clientlauncher.cpp msgid "Provided world path doesn't exist: " -msgstr "" +msgstr "O caminho fornecido não existe: " #: src/fontengine.cpp +#, fuzzy msgid "needs_fallback_font" -msgstr "no" +msgstr "needs_fallback_font" #: src/game.cpp msgid "" @@ -699,6 +687,18 @@ msgid "" "- touch&drag, tap 2nd finger\n" " --> place single item to slot\n" msgstr "" +"Controles:\n" +"Se não há nenhum menu visível:\n" +"- Um toque: ativa botão\n" +"- Duplo toque: place/use\n" +"- Deslizar dedo: Olhar ao redor\n" +"Menu/Inventário visível:\n" +"- Duplo toque: (Fora do menu):\n" +" -->Fechar\n" +"- Tocar Item e depois tocar em um slot:\n" +" --> move item\n" +"- Tocar e arrastar, e depois tocar com o 2º dedo\n" +" --> Coloca apenas um item no slot\n" #: src/game.cpp msgid "Exit to Menu" @@ -710,11 +710,11 @@ msgstr "Sair do Minetest" #: src/game.cpp msgid "Item definitions..." -msgstr "Definições dos itens..." +msgstr "Carregando itens..." #: src/game.cpp msgid "KiB/s" -msgstr "" +msgstr "KB/s" #: src/game.cpp msgid "Media..." @@ -722,11 +722,11 @@ msgstr "Mídia..." #: src/game.cpp msgid "MiB/s" -msgstr "" +msgstr "MB/s" #: src/game.cpp msgid "Node definitions..." -msgstr "Definições dos nós..." +msgstr "Carregando blocos..." #: src/game.cpp src/guiFormSpecMenu.cpp msgid "Proceed" @@ -754,12 +754,13 @@ msgid "You died." msgstr "Você morreu." #: src/guiFormSpecMenu.cpp +#, fuzzy msgid "Enter " -msgstr "" +msgstr "Entrar " #: src/guiFormSpecMenu.cpp msgid "ok" -msgstr "" +msgstr "Ok" #: src/guiKeyChangeMenu.cpp msgid "\"Use\" = climb down" @@ -832,9 +833,8 @@ msgid "Sneak" msgstr "Esgueirar" #: src/guiKeyChangeMenu.cpp -#, fuzzy msgid "Toggle Cinematic" -msgstr "Alternar corrida" +msgstr "Alternar modo de câmera cinemática" #: src/guiKeyChangeMenu.cpp msgid "Toggle fast" @@ -1185,7 +1185,7 @@ msgstr "Nuvens 3D" #: src/settings_translation_file.cpp msgid "3D mode" -msgstr "" +msgstr "modo 3D" #: src/settings_translation_file.cpp msgid "" @@ -1197,20 +1197,33 @@ msgid "" "- topbottom: split screen top/bottom.\n" "- sidebyside: split screen side by side." msgstr "" +"Suporte 3D.\n" +"Modos atualmente suportados:\n" +"- none: Nenhum efeito 3D.\n" +"- anaglyph: Sistema de cor Ciano/Magenta (Óculos 3D azul vermelho).\n" +"- interlaced: Sistema interlaçado (Óculos com lentes polarizadas).\n" +"- topbottom: Divide a tela em duas: uma em cima e outra em baixo.\n" +"- sidebyside: Divide a tela em duas: lado a lado." #: src/settings_translation_file.cpp msgid "" "A chosen map seed for a new map, leave empty for random.\n" "Will be overridden when creating a new world in the main menu." msgstr "" +"Seed do mundo (deixe em branco para uma seed aleatória).\n" +"Será sobrescrita quando for criada um novo mundo no menu principal." #: src/settings_translation_file.cpp msgid "A message to be displayed to all clients when the server crashes." msgstr "" +"Uma mensagem para ser mostrada a todos os clientes do seu servidor quando " +"ele travar." #: src/settings_translation_file.cpp msgid "A message to be displayed to all clients when the server shuts down." msgstr "" +"Uma mensagem para ser mostrada a todos os clientes quando o servidor " +"desligar." #: src/settings_translation_file.cpp msgid "Absolute limit of emerge queues" @@ -1218,11 +1231,11 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Acceleration in air" -msgstr "" +msgstr "Aceleração no ar" #: src/settings_translation_file.cpp msgid "Active block range" -msgstr "" +msgstr "Limite para blocos ativos" #: src/settings_translation_file.cpp msgid "Active object send range" @@ -1234,12 +1247,17 @@ msgid "" "Leave this blank to start a local server.\n" "Note that the address field in the main menu overrides this setting." msgstr "" +"Endereço para conexão.\n" +"Deixe em branco para iniciar um servidor local.\n" +"Note que o campo de endereço no menu principal sobrescreve essa configuração." #: src/settings_translation_file.cpp msgid "" "Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k " "screens." msgstr "" +"Ajustar configuração de dpi (profundidade de cor) para sua tela (apenas para " +"quem não usa X11/Android) Ex para telas 4K" #: src/settings_translation_file.cpp msgid "" @@ -1266,7 +1284,7 @@ msgstr "Filtragem anisotrópica" #: src/settings_translation_file.cpp msgid "Announce server" -msgstr "" +msgstr "Anunciar servidor" #: src/settings_translation_file.cpp msgid "" @@ -1290,7 +1308,7 @@ msgstr "Voltar" #: src/settings_translation_file.cpp msgid "Basic" -msgstr "" +msgstr "Básico" #: src/settings_translation_file.cpp #, fuzzy @@ -1305,11 +1323,12 @@ msgstr "Resolvendo os endereços..." #: src/settings_translation_file.cpp msgid "Bits per pixel (aka color depth) in fullscreen mode." msgstr "" +"Bits por pixel (Também conhecido como profundidade de cor) no modo de tela " +"cheia." #: src/settings_translation_file.cpp -#, fuzzy msgid "Build inside player" -msgstr "Vários jogadores" +msgstr "Construir com o jogador dentro do bloco" #: src/settings_translation_file.cpp #, fuzzy @@ -1318,15 +1337,15 @@ msgstr "Mipmapping" #: src/settings_translation_file.cpp msgid "Camera smoothing" -msgstr "" +msgstr "Suavização da camera" #: src/settings_translation_file.cpp msgid "Camera smoothing in cinematic mode" -msgstr "" +msgstr "Suavização da câmera no modo cinematográfico" #: src/settings_translation_file.cpp msgid "Camera update toggle key" -msgstr "" +msgstr "Tecla para alternar atualização da câmera" #: src/settings_translation_file.cpp #, fuzzy @@ -1343,14 +1362,12 @@ msgid "Chunk size" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Cinematic mode" -msgstr "Modo criativo" +msgstr "Modo cinematográfico" #: src/settings_translation_file.cpp -#, fuzzy msgid "Cinematic mode key" -msgstr "Modo criativo" +msgstr "Tecla para modo cinematográfico" #: src/settings_translation_file.cpp msgid "Clean transparent textures" @@ -1358,43 +1375,44 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Client and Server" -msgstr "" +msgstr "Cliente e servidor" #: src/settings_translation_file.cpp msgid "Climbing speed" -msgstr "" +msgstr "Velocidade de subida (em escadas e outros)" #: src/settings_translation_file.cpp msgid "Cloud height" -msgstr "" +msgstr "Altura das nuvens" #: src/settings_translation_file.cpp msgid "Cloud radius" -msgstr "" +msgstr "Espessura das nuvens" #: src/settings_translation_file.cpp -#, fuzzy msgid "Clouds" -msgstr "Nuvens 3D" +msgstr "Nuvens" #: src/settings_translation_file.cpp msgid "Clouds are a client side effect." -msgstr "" +msgstr "Conf. das nuvens apenas afetam seu jogo local." #: src/settings_translation_file.cpp -#, fuzzy msgid "Clouds in menu" -msgstr "Menu principal" +msgstr "Nuvens no menu" #: src/settings_translation_file.cpp msgid "Colored fog" -msgstr "" +msgstr "Névoa colorida" #: src/settings_translation_file.cpp msgid "" "Comma-separated list of trusted mods that are allowed to access insecure\n" "functions even when mod security is on (via request_insecure_environment())." msgstr "" +"Lista separada por vírgulas dos mods confiáveis que podem utilizar funções " +"inseguras mesmo quando o a opção de Mod Seguro está ativada (via " +"request_insecure_environment())." #: src/settings_translation_file.cpp #, fuzzy @@ -1402,41 +1420,36 @@ msgid "Command key" msgstr "Comando" #: src/settings_translation_file.cpp -#, fuzzy msgid "Connect glass" -msgstr "Conectar" +msgstr "Vidro conectado" #: src/settings_translation_file.cpp -#, fuzzy msgid "Connect to external media server" -msgstr "Conectando ao servidor..." +msgstr "Conectando ao servidor de mídia externo..." #: src/settings_translation_file.cpp msgid "Connects glass if supported by node." -msgstr "" +msgstr "Conecta o vidro se isso for suportado pelo bloco." #: src/settings_translation_file.cpp -#, fuzzy msgid "Console alpha" -msgstr "Console" +msgstr "Console Alpha" #: src/settings_translation_file.cpp -#, fuzzy msgid "Console color" -msgstr "Console" +msgstr "Cor do console" #: src/settings_translation_file.cpp -#, fuzzy msgid "Console key" -msgstr "Console" +msgstr "Tecla do console" #: src/settings_translation_file.cpp msgid "Continuous forward" -msgstr "" +msgstr "Para frente continuamente" #: src/settings_translation_file.cpp msgid "Continuous forward movement (only used for testing)." -msgstr "" +msgstr "Movimento contínuo para frente (apenas usado para testes)." #: src/settings_translation_file.cpp #, fuzzy @@ -1449,81 +1462,86 @@ msgid "" "Examples: 72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays " "unchanged." msgstr "" +"Controles da duração do dia.\n" +"Exemplos: 72 = 20min, 360 = 4min, 1 = 24hour, 0 = O tempo para e permanece " +"inalterado." #: src/settings_translation_file.cpp msgid "" "Controls size of deserts and beaches in Mapgen v6.\n" "When snowbiomes are enabled 'mgv6_freq_desert' is ignored." msgstr "" +"Controla o tamanho dos desertos e das praias no Mapgen v6.\n" +"Quando \"snowbiomes\" (bioma de neve) está habilitado 'mgv6_freq_desert' é " +"ignorado." #: src/settings_translation_file.cpp msgid "Crash message" -msgstr "" +msgstr "Mensagem de travamento" #: src/settings_translation_file.cpp msgid "Crosshair alpha" -msgstr "" +msgstr "Alpha do cursor" #: src/settings_translation_file.cpp msgid "Crosshair alpha (opaqueness, between 0 and 255)." -msgstr "" +msgstr "Alpha do cursor (o quanto ele é opaco, níveis entre 0 e 255)." #: src/settings_translation_file.cpp msgid "Crosshair color" -msgstr "" +msgstr "Cor do cursor" #: src/settings_translation_file.cpp msgid "Crosshair color (R,G,B)." -msgstr "" +msgstr "Cor do cursor (R,G,B)." #: src/settings_translation_file.cpp msgid "Crouch speed" -msgstr "" +msgstr "Velocidade para descer" #: src/settings_translation_file.cpp msgid "DPI" -msgstr "" +msgstr "dpi" #: src/settings_translation_file.cpp -#, fuzzy msgid "Damage" -msgstr "Habilitar dano" +msgstr "Dano" #: src/settings_translation_file.cpp msgid "Debug info toggle key" -msgstr "" +msgstr "Tecla para alternar modo de Debug" #: src/settings_translation_file.cpp msgid "Debug log level" -msgstr "" +msgstr "Nível de log do Debug" #: src/settings_translation_file.cpp msgid "Dedicated server step" -msgstr "" +msgstr "Passo do servidor dedicado" #: src/settings_translation_file.cpp msgid "Default acceleration" -msgstr "" +msgstr "Aceleração padrão" #: src/settings_translation_file.cpp -#, fuzzy msgid "Default game" -msgstr "editar o jogo" +msgstr "Jogo padrão" #: src/settings_translation_file.cpp msgid "" "Default game when creating a new world.\n" "This will be overridden when creating a world from the main menu." msgstr "" +"Padrões de jogo para quando criar um novo mundo.\n" +"Isso será sobrescrito quando criar um mundo no menu principal." #: src/settings_translation_file.cpp -#, fuzzy msgid "Default password" -msgstr "Nova senha" +msgstr "Senha padrão" #: src/settings_translation_file.cpp msgid "Default privileges" -msgstr "" +msgstr "Privilégios por padrão" #: src/settings_translation_file.cpp msgid "" @@ -1572,17 +1590,16 @@ msgid "Detailed mod profiling" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Disable anticheat" -msgstr "Habilitar partículas" +msgstr "Habilitar Anti-Hack" #: src/settings_translation_file.cpp msgid "Disallow empty passwords" -msgstr "" +msgstr "Não permitir logar sem senha" #: src/settings_translation_file.cpp msgid "Domain name of server, to be displayed in the serverlist." -msgstr "" +msgstr "Domínio do servidor, para ser mostrado na lista de servidores." #: src/settings_translation_file.cpp #, fuzzy @@ -1596,11 +1613,11 @@ msgstr "\"Pular\" duas vezes ativa o voo" #: src/settings_translation_file.cpp msgid "Drop item key" -msgstr "" +msgstr "Tecla para largar item" #: src/settings_translation_file.cpp msgid "Dump the mapgen debug infos." -msgstr "" +msgstr "Mostrar informações de depuração do Mapgen." #: src/settings_translation_file.cpp msgid "" @@ -1609,23 +1626,28 @@ msgid "" "Note that this is not quite optimized and that smooth lighting on the\n" "water surface doesn't work with this." msgstr "" +"Habilita recurso permitindo que o nível da água seja um pouco menor, " +"portando não preenche todo o espaço disponível para bloco.\n" +"Note que isso não está bem otimizado e que suavização da iluminação na " +"superfície da água não funciona bem com esse recurso." #: src/settings_translation_file.cpp -#, fuzzy msgid "Enable mod security" -msgstr "Repositório de módulos online" +msgstr "Habilitar Mod Security (Segurança nos mods)" #: src/settings_translation_file.cpp msgid "Enable players getting damage and dying." -msgstr "" +msgstr "Permitir que os jogadores possam sofrer dano e morrer." #: src/settings_translation_file.cpp msgid "Enable random user input (only used for testing)." -msgstr "" +msgstr "Habilitar entrada de comandos aleatórios (apenas usado para testes)." #: src/settings_translation_file.cpp msgid "Enable selection highlighting for nodes (disables selectionbox)." msgstr "" +"Habilitar destaque de bloco selecionado (desabilita o modo de destaque " +"selectionbox [Padrão])." #: src/settings_translation_file.cpp msgid "" @@ -1641,6 +1663,11 @@ msgid "" "to new servers, but they may not support all new features that you are " "expecting." msgstr "" +"Habilitar recurso de não permitir que jogadores usando versões antigas do " +"cliente possam se conectar.\n" +"Essas versões são compatíveis no sentido de não travar quando conectam a " +"servidores com versões mais atuais, porém eles podem não suportar todos os " +"recursos que você está esperando." #: src/settings_translation_file.cpp msgid "" @@ -1670,9 +1697,8 @@ msgid "Enables caching of facedir rotated meshes." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Enables minimap." -msgstr "Habilitar dano" +msgstr "Habilitar minimapa." #: src/settings_translation_file.cpp msgid "" @@ -1745,17 +1771,19 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Field of view" -msgstr "" +msgstr "Campo de visão" #: src/settings_translation_file.cpp msgid "Field of view in degrees." -msgstr "" +msgstr "Campo de visão em graus." #: src/settings_translation_file.cpp msgid "" "File in client/serverlist/ that contains your favorite servers displayed in " "the Multiplayer Tab." msgstr "" +"Arquivo na pasta client/serverlist/ que contém seus servidores favoritos, " +"que são mostrados na aba Multiplayer." #: src/settings_translation_file.cpp msgid "" From c07a242d8be1fef1565e7bb8797070f614f56fe2 Mon Sep 17 00:00:00 2001 From: Tobyplowy Date: Sat, 23 Jan 2016 04:35:25 +0100 Subject: [PATCH 61/68] Translated using Weblate (Dutch) Currently translated at 95.5% (752 of 787 strings) --- po/nl/minetest.po | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/po/nl/minetest.po b/po/nl/minetest.po index 44f807c79..8a499085a 100644 --- a/po/nl/minetest.po +++ b/po/nl/minetest.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-12-19 02:35+0000\n" -"Last-Translator: Rogier \n" +"PO-Revision-Date: 2016-01-23 04:35+0000\n" +"Last-Translator: Tobyplowy \n" "Language-Team: Dutch " "\n" "Language: nl\n" @@ -568,12 +568,12 @@ msgstr "Voorwerp-texturen..." #: src/client.cpp msgid "Loading textures..." -msgstr "Bezig met laden van texturen..." +msgstr "Bezig met texturen te laaden..." #: src/client.cpp #, fuzzy msgid "Rebuilding shaders..." -msgstr "Herbouwen van shaders..." +msgstr "schaduwen herbouwen..." #: src/client/clientlauncher.cpp msgid "Connection error (timed out?)" @@ -731,7 +731,7 @@ msgstr "Server-adres opzoeken..." #: src/game.cpp msgid "Respawn" -msgstr "Wedergeboorte" +msgstr "Respawn" #: src/game.cpp msgid "Shutting down..." @@ -743,16 +743,15 @@ msgstr "Geluidsvolume" #: src/game.cpp msgid "You died." -msgstr "Je bent gestorven." +msgstr "Je bent dood." #: src/guiFormSpecMenu.cpp -#, fuzzy msgid "Enter " -msgstr "Invoeren " +msgstr "Enter " #: src/guiFormSpecMenu.cpp msgid "ok" -msgstr "ok" +msgstr "oké" #: src/guiKeyChangeMenu.cpp msgid "\"Use\" = climb down" @@ -788,7 +787,7 @@ msgstr "Vooruit" #: src/guiKeyChangeMenu.cpp msgid "Inventory" -msgstr "Rugzak" +msgstr "inventaris" #: src/guiKeyChangeMenu.cpp msgid "Jump" @@ -822,7 +821,7 @@ msgstr "Rechts" #: src/guiKeyChangeMenu.cpp msgid "Sneak" -msgstr "Kruipen" +msgstr "sluipen" #: src/guiKeyChangeMenu.cpp msgid "Toggle Cinematic" @@ -1364,7 +1363,7 @@ msgstr "Cinematic modus aan/uit toets" #: src/settings_translation_file.cpp #, fuzzy msgid "Clean transparent textures" -msgstr "Doorzichtige texturen schonen" +msgstr "Transparante texturen" #: src/settings_translation_file.cpp msgid "Client and Server" @@ -1691,6 +1690,10 @@ msgid "" "or need to be auto-generated.\n" "Requires shaders to be enabled." msgstr "" +"bumpmapping aanzetten voor texturen. Normalmaps moeten al in de texture pack " +"zitten\n" +"of ze moeten automatisch gegenereerd worden.\n" +"Schaduwen moeten aanstaan." #: src/settings_translation_file.cpp msgid "Enables caching of facedir rotated meshes." @@ -1726,7 +1729,7 @@ msgstr "FPS in het pauze-menu" #: src/settings_translation_file.cpp msgid "FSAA" -msgstr "" +msgstr "FSAA" #: src/settings_translation_file.cpp msgid "Fall bobbing" From 0097e0308d8a7f5d660533fe7a6d47b2b769636b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kisbenedek=20M=C3=A1rton?= Date: Mon, 25 Jan 2016 00:59:19 +0100 Subject: [PATCH 62/68] Translated using Weblate (Hungarian) Currently translated at 32.4% (255 of 787 strings) --- po/hu/minetest.po | 140 ++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/po/hu/minetest.po b/po/hu/minetest.po index 38468e171..f34f0fc23 100644 --- a/po/hu/minetest.po +++ b/po/hu/minetest.po @@ -8,16 +8,16 @@ msgstr "" "Project-Id-Version: minetest\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-09-21 14:55+0200\n" -"Last-Translator: way-hu \n" -"Language-Team: Hungarian \n" +"PO-Revision-Date: 2016-01-25 00:59+0000\n" +"Last-Translator: Kisbenedek Márton \n" +"Language-Team: Hungarian " +"\n" "Language: hu\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: Weblate 2.4\n" +"X-Generator: Weblate 2.5-dev\n" #: builtin/fstk/ui.lua msgid "An error occured in a Lua script, such as a mod:" @@ -48,9 +48,8 @@ msgid "Loading..." msgstr "Betöltés..." #: builtin/mainmenu/common.lua -#, fuzzy msgid "Protocol version mismatch. " -msgstr "Protokol verzió eltérés, szerver " +msgstr "Protokoll verzió eltérés. " #: builtin/mainmenu/common.lua msgid "Server enforces protocol version $1. " @@ -58,7 +57,7 @@ msgstr "" #: builtin/mainmenu/common.lua msgid "Server supports protocol versions between $1 and $2. " -msgstr "" +msgstr "A szerver $1 és $2 protokoll verzió közötti verziókat támogat. " #: builtin/mainmenu/common.lua msgid "Try reenabling public serverlist and check your internet connection." @@ -68,11 +67,11 @@ msgstr "" #: builtin/mainmenu/common.lua msgid "We only support protocol version $1." -msgstr "" +msgstr "Csak $1 protokoll verziót támogatjuk." #: builtin/mainmenu/common.lua msgid "We support protocol versions between version $1 and $2." -msgstr "" +msgstr "$1 és $2 közötti protokoll verziókat támogatunk." #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_create_world.lua #: builtin/mainmenu/dlg_rename_modpack.lua builtin/mainmenu/tab_settings.lua @@ -82,7 +81,7 @@ msgstr "Mégse" #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_mods.lua msgid "Depends:" -msgstr "Függőségek:" +msgstr "Függ:" #: builtin/mainmenu/dlg_config_world.lua msgid "Disable MP" @@ -94,7 +93,7 @@ msgstr "Csomag engedélyez" #: builtin/mainmenu/dlg_config_world.lua msgid "Enable all" -msgstr "Összes engedélyezése" +msgstr "Mind engedélyez" #: builtin/mainmenu/dlg_config_world.lua msgid "" @@ -106,11 +105,11 @@ msgstr "" #: builtin/mainmenu/dlg_config_world.lua msgid "Hide Game" -msgstr "Játék elrejtése" +msgstr "Játék elrejtés" #: builtin/mainmenu/dlg_config_world.lua msgid "Hide mp content" -msgstr "Modpakk tartalom elrejtése" +msgstr "Modpakk tartalom elrejtés" #: builtin/mainmenu/dlg_config_world.lua msgid "Mod:" @@ -135,7 +134,7 @@ msgstr "\"$1\" nevű világ már létezik" #: builtin/mainmenu/dlg_create_world.lua msgid "Create" -msgstr "Létrehozás" +msgstr "Létrehoz" #: builtin/mainmenu/dlg_create_world.lua msgid "Download a subgame, such as minetest_game, from minetest.net" @@ -208,7 +207,7 @@ msgstr "Elfogad" #: builtin/mainmenu/dlg_rename_modpack.lua msgid "Rename Modpack:" -msgstr "Modpakk átnevezése:" +msgstr "Modpakk átnevezés:" #: builtin/mainmenu/modmgr.lua msgid "" @@ -370,7 +369,7 @@ msgstr "Bind Address" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_singleplayer.lua msgid "Configure" -msgstr "Beállítás" +msgstr "Beállít" #: builtin/mainmenu/tab_server.lua builtin/mainmenu/tab_simple_main.lua #: builtin/mainmenu/tab_singleplayer.lua @@ -428,20 +427,19 @@ msgstr "" #: builtin/mainmenu/tab_settings.lua msgid "Browse" -msgstr "" +msgstr "Keres" #: builtin/mainmenu/tab_settings.lua msgid "Change keys" msgstr "Gombok változtatása" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Disabled" -msgstr "Csomag letiltás" +msgstr "Letiltva" #: builtin/mainmenu/tab_settings.lua msgid "Edit" -msgstr "" +msgstr "Szerkeszt" #: builtin/mainmenu/tab_settings.lua #, fuzzy @@ -450,7 +448,7 @@ msgstr "Engedélyez" #: builtin/mainmenu/tab_settings.lua msgid "Format is 3 numbers separated by commas and inside brackets." -msgstr "" +msgstr "A formátum 3 szám vesszőkkel elválasztva zárójelek között." #: builtin/mainmenu/tab_settings.lua msgid "" @@ -459,9 +457,8 @@ msgid "" msgstr "" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Games" -msgstr "Játék" +msgstr "Játékok" #: builtin/mainmenu/tab_settings.lua msgid "Optionally the lacunarity can be appended with a leading comma." @@ -473,24 +470,23 @@ msgstr "" #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid integer." -msgstr "" +msgstr "Írj be egy érvényes egész számot." #: builtin/mainmenu/tab_settings.lua msgid "Please enter a valid number." -msgstr "" +msgstr "Írj be egy érvényes számot." #: builtin/mainmenu/tab_settings.lua msgid "Possible values are: " -msgstr "" +msgstr "Lehetséges értékek: " #: builtin/mainmenu/tab_settings.lua msgid "Restore Default" -msgstr "" +msgstr "Alapértelmezett visszaállítás" #: builtin/mainmenu/tab_settings.lua -#, fuzzy msgid "Select path" -msgstr "Kiválaszt" +msgstr "Útvonal kiválasztás" #: builtin/mainmenu/tab_settings.lua msgid "Settings" @@ -498,15 +494,15 @@ msgstr "Beállítások" #: builtin/mainmenu/tab_settings.lua msgid "Show technical names" -msgstr "" +msgstr "Technikai nevek mutatása" #: builtin/mainmenu/tab_settings.lua msgid "The value must be greater than $1." -msgstr "" +msgstr "Az értéknek nagyobbnak kell lennie ennél: $1." #: builtin/mainmenu/tab_settings.lua msgid "The value must be lower than $1." -msgstr "" +msgstr "Az értéknek kisebbnek kell lennie ennél: $1." #: builtin/mainmenu/tab_simple_main.lua msgid "Config mods" @@ -526,7 +522,7 @@ msgstr "Játék" #: builtin/mainmenu/tab_singleplayer.lua msgid "Singleplayer" -msgstr "Egyjátékos mód" +msgstr "Egyjátékos" #: builtin/mainmenu/tab_texturepacks.lua msgid "No information available" @@ -538,7 +534,7 @@ msgstr "Semmi" #: builtin/mainmenu/tab_texturepacks.lua msgid "Select texture pack:" -msgstr "Textúracsomag kiválasztása:" +msgstr "Textúrapakk kiválasztása:" #: builtin/mainmenu/tab_texturepacks.lua msgid "Texturepacks" @@ -655,13 +651,13 @@ msgstr "" "Alapértelmezett irányítás:\n" "- WASD: Mozgás\n" "- Space: Ugrás/Mászás\n" -"- Shift: Lopakodás/Lefele menés\n" +"- Shift: Lopakodás/Lefelé\n" "- Q: Tárgyak eldobása\n" -"- I: Invertory\n" +"- I: Eszköztár\n" "- Egér: Forgás/Nézelődés\n" -"- Egér Bal-gomb: Ásás/Ütés\n" -"- Egér jobb-gomb: Helyezés/Használat\n" -"- Egér görgő: Tárgyak kiválasztása\n" +"- Bal-egér: Ásás/Ütés\n" +"- Jobb-egér: Helyez/Használ\n" +"- Egér görgő: Tárgy kiválaszt\n" "- T: Beszélgetés\n" #: src/game.cpp @@ -684,7 +680,7 @@ msgstr "" "- egy érintés: gomb aktiválás\n" "- dupla érintés: helyez/használat\n" "- ujj csúsztatás: körbenéz\n" -"Menü/Inventory látható:\n" +"Menü/Eszköztár látható:\n" "- dupla érintés (külső):\n" " -->bezár\n" "- stack, vagy slot érintése:\n" @@ -698,7 +694,7 @@ msgstr "Kilépés a menübe" #: src/game.cpp msgid "Exit to OS" -msgstr "Kilépés az OP-rendszerbe" +msgstr "Bezárás" #: src/game.cpp msgid "Item definitions..." @@ -785,9 +781,8 @@ msgid "Forward" msgstr "Előre" #: src/guiKeyChangeMenu.cpp -#, fuzzy msgid "Inventory" -msgstr "Inventory" +msgstr "Eszköztár" #: src/guiKeyChangeMenu.cpp msgid "Jump" @@ -800,7 +795,7 @@ msgstr "A gomb már használatban van" #: src/guiKeyChangeMenu.cpp msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" msgstr "" -"Gombkiosztás. (Ha elfuserálod ezt a menüt, távolíts el néhány cuccot a " +"Gombkiosztás. (Ha elfuserálod ezt a menüt, távolíts el néhány dolgot a " "minetest.conf-ból)" #: src/guiKeyChangeMenu.cpp src/keycode.cpp @@ -809,7 +804,7 @@ msgstr "Bal" #: src/guiKeyChangeMenu.cpp src/settings_translation_file.cpp msgid "Print stacks" -msgstr "Stacks nyomtatása" +msgstr "Halmok nyomtatása" #: src/guiKeyChangeMenu.cpp msgid "Range select" @@ -976,7 +971,7 @@ msgstr "Bal gomb" #: src/keycode.cpp msgid "Left Control" -msgstr "Bal Controll" +msgstr "Bal Control" #: src/keycode.cpp msgid "Left Menu" @@ -1020,59 +1015,59 @@ msgstr "Numlock" #: src/keycode.cpp msgid "Numpad *" -msgstr "Numerikus billentyű *" +msgstr "Numerikus bill. *" #: src/keycode.cpp msgid "Numpad +" -msgstr "Numerikus billentyű +" +msgstr "Numerikus bill. +" #: src/keycode.cpp msgid "Numpad -" -msgstr "Numerikus billentyű -" +msgstr "Numerikus bill. -" #: src/keycode.cpp msgid "Numpad /" -msgstr "Numerikus billentyű /" +msgstr "Numerikus bill. /" #: src/keycode.cpp msgid "Numpad 0" -msgstr "Numerikus billentyű 0" +msgstr "Numerikus bill. 0" #: src/keycode.cpp msgid "Numpad 1" -msgstr "Numerikus billentyű 1" +msgstr "Numerikus bill. 1" #: src/keycode.cpp msgid "Numpad 2" -msgstr "Numerikus billentyű 2" +msgstr "Numerikus bill. 2" #: src/keycode.cpp msgid "Numpad 3" -msgstr "Numerikus billentyű 3" +msgstr "Numerikus bill. 3" #: src/keycode.cpp msgid "Numpad 4" -msgstr "Numerikus billentyű 4" +msgstr "Numerikus bill. 4" #: src/keycode.cpp msgid "Numpad 5" -msgstr "Numerikus billentyű 5" +msgstr "Numerikus bill. 5" #: src/keycode.cpp msgid "Numpad 6" -msgstr "Numerikus billentyű 6" +msgstr "Numerikus bill. 6" #: src/keycode.cpp msgid "Numpad 7" -msgstr "Numerikus billentyű 7" +msgstr "Numerikus bill. 7" #: src/keycode.cpp msgid "Numpad 8" -msgstr "Numerikus billentyű 8" +msgstr "Numerikus bill. 8" #: src/keycode.cpp msgid "Numpad 9" -msgstr "Numerikus billentyű 9" +msgstr "Numerikus bill. 9" #: src/keycode.cpp #, fuzzy @@ -1174,10 +1169,13 @@ msgid "Zoom" msgstr "Nagyítás" #: src/settings_translation_file.cpp +#, fuzzy msgid "" "0 = parallax occlusion with slope information (faster).\n" "1 = relief mapping (slower, more accurate)." msgstr "" +"0 = parallax occlusion with slope information (gyorsabb).\n" +"1 = relief mapping (lassabb, pontosabb)." #: src/settings_translation_file.cpp #, fuzzy @@ -1186,9 +1184,10 @@ msgstr "3D felhők" #: src/settings_translation_file.cpp msgid "3D mode" -msgstr "" +msgstr "3D mód" #: src/settings_translation_file.cpp +#, fuzzy msgid "" "3D support.\n" "Currently supported:\n" @@ -1198,20 +1197,29 @@ msgid "" "- topbottom: split screen top/bottom.\n" "- sidebyside: split screen side by side." msgstr "" +"3D támogatás.\n" +"Jelenleg támogatott:\n" +"- none: nincs 3d kimenet.\n" +"- anaglyph: cián/magenta színű 3d.\n" +"- interlaced: odd/even line based polarisation screen support.\n" +"- topbottom: split screen top/bottom.\n" +"- sidebyside: split screen side by side." #: src/settings_translation_file.cpp msgid "" "A chosen map seed for a new map, leave empty for random.\n" "Will be overridden when creating a new world in the main menu." msgstr "" +"Egy választott map seed az új térképhez, véletlenszerűhöz hagyd üresen.\n" +"Felül lesz írva új világ létrehozásánál a főmenüben." #: src/settings_translation_file.cpp msgid "A message to be displayed to all clients when the server crashes." -msgstr "" +msgstr "Az összes kliensen megjelenített üzenet a szerver összeomlásakor." #: src/settings_translation_file.cpp msgid "A message to be displayed to all clients when the server shuts down." -msgstr "" +msgstr "Az összes kliensen megjelenített üzenet a szerver leállításakor." #: src/settings_translation_file.cpp msgid "Absolute limit of emerge queues" @@ -1219,11 +1227,11 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Acceleration in air" -msgstr "" +msgstr "Gyorsulás levegőben" #: src/settings_translation_file.cpp msgid "Active block range" -msgstr "" +msgstr "Aktív blokk kiterjedési terület" #: src/settings_translation_file.cpp msgid "Active object send range" From e52ebda8b2273bbd80573838d6dbafb31ee2cd2b Mon Sep 17 00:00:00 2001 From: Paolo DGZ Date: Sun, 24 Jan 2016 15:00:55 +0100 Subject: [PATCH 63/68] Translated using Weblate (Italian) Currently translated at 52.0% (410 of 787 strings) --- po/it/minetest.po | 196 +++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 116 deletions(-) diff --git a/po/it/minetest.po b/po/it/minetest.po index b6acf55e0..80858d29c 100644 --- a/po/it/minetest.po +++ b/po/it/minetest.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: Minetest 0.4.9\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-11-08 21:23+0100\n" -"PO-Revision-Date: 2015-12-21 22:09+0000\n" -"Last-Translator: Gianluca Luparini \n" +"PO-Revision-Date: 2016-01-24 15:00+0000\n" +"Last-Translator: Paolo DGZ \n" "Language-Team: Italian " "\n" "Language: it\n" @@ -42,7 +42,7 @@ msgstr "Riconnettersi" #: builtin/fstk/ui.lua msgid "The server has requested a reconnect:" -msgstr "Il server ha richiesto una riconnessione" +msgstr "Il server ha richiesto una riconnessione:" #: builtin/mainmenu/common.lua src/game.cpp msgid "Loading..." @@ -78,7 +78,7 @@ msgstr "Supportiamo soltanto versioni del protocollo comprese tra $1 e $2." #: builtin/mainmenu/dlg_rename_modpack.lua builtin/mainmenu/tab_settings.lua #: src/guiKeyChangeMenu.cpp src/keycode.cpp msgid "Cancel" -msgstr "Annullare" +msgstr "Annulla" #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_mods.lua msgid "Depends:" @@ -86,15 +86,15 @@ msgstr "Dipendenze:" #: builtin/mainmenu/dlg_config_world.lua msgid "Disable MP" -msgstr "Disatt. pacch." +msgstr "Disattiva modpack" #: builtin/mainmenu/dlg_config_world.lua msgid "Enable MP" -msgstr "Att. pacch." +msgstr "Attiva modpack" #: builtin/mainmenu/dlg_config_world.lua msgid "Enable all" -msgstr "Attivarli tutti" +msgstr "Attivali tutti" #: builtin/mainmenu/dlg_config_world.lua msgid "" @@ -119,7 +119,7 @@ msgstr "Mod.:" #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_settings.lua #: src/guiKeyChangeMenu.cpp msgid "Save" -msgstr "Salvare" +msgstr "Salva" #: builtin/mainmenu/dlg_config_world.lua msgid "World:" @@ -135,7 +135,7 @@ msgstr "Esiste già un mondo chiamato \"$1\"" #: builtin/mainmenu/dlg_create_world.lua msgid "Create" -msgstr "Creare" +msgstr "Crea" #: builtin/mainmenu/dlg_create_world.lua msgid "Download a subgame, such as minetest_game, from minetest.net" @@ -325,7 +325,7 @@ msgstr "Selezionare il file modulo:" #: builtin/mainmenu/tab_mods.lua msgid "Uninstall selected mod" -msgstr "Disinstallare il modulo selezionato" +msgstr "Disinstalla la mod selezionata" #: builtin/mainmenu/tab_mods.lua msgid "Uninstall selected modpack" @@ -341,7 +341,7 @@ msgstr "Client" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Connect" -msgstr "Connettere" +msgstr "Connettiti" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_simple_main.lua msgid "Creative mode" @@ -354,7 +354,7 @@ msgstr "Danni abilitati" #: builtin/mainmenu/tab_multiplayer.lua builtin/mainmenu/tab_server.lua #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp msgid "Delete" -msgstr "Cancellare" +msgstr "Cancella" #: builtin/mainmenu/tab_multiplayer.lua msgid "Name / Password :" @@ -607,7 +607,7 @@ msgstr "Il percorso del mondo fornito non esiste: " #: src/fontengine.cpp msgid "needs_fallback_font" -msgstr "no" +msgstr "richiedi_fallback_font" #: src/game.cpp msgid "" @@ -618,9 +618,8 @@ msgstr "" "Controllare debug.txt per i dettagli." #: src/game.cpp -#, fuzzy msgid "Change Keys" -msgstr "Cambiare i tasti" +msgstr "Cambia i tasti" #: src/game.cpp msgid "Change Password" @@ -703,7 +702,7 @@ msgstr "Tornare al menù" #: src/game.cpp msgid "Exit to OS" -msgstr "Tornare al S.O." +msgstr "Tornare al sistema operativo" #: src/game.cpp msgid "Item definitions..." @@ -910,7 +909,7 @@ msgstr "Control" #: src/keycode.cpp msgid "Convert" -msgstr "Convert" +msgstr "Converti" #: src/keycode.cpp msgid "CrSel" @@ -926,7 +925,7 @@ msgstr "Fine" #: src/keycode.cpp msgid "Erase OEF" -msgstr "Erase OEF" +msgstr "Cancella OEF" #: src/keycode.cpp msgid "Escape" @@ -1074,7 +1073,7 @@ msgstr "Tast. num. 9" #: src/keycode.cpp msgid "OEM Clear" -msgstr "OEM Clear" +msgstr "Ripulisci OEM" #: src/keycode.cpp msgid "PA1" @@ -1221,9 +1220,8 @@ msgstr "" "Un messaggio da mostrare a tutti i giocatori quando il server si spegne." #: src/settings_translation_file.cpp -#, fuzzy msgid "Absolute limit of emerge queues" -msgstr "Limite assoluto delle code di \"emersione\"" +msgstr "Limite assoluto delle code degli emerge" #: src/settings_translation_file.cpp msgid "Acceleration in air" @@ -1267,7 +1265,7 @@ msgstr "Avanzato" #: src/settings_translation_file.cpp msgid "Always fly and fast" -msgstr "" +msgstr "Volo veloce permanentemente abilitato" #: src/settings_translation_file.cpp #, fuzzy @@ -1337,14 +1335,13 @@ msgstr "Ammorbidisci la visuale in modalità cinematica" #: src/settings_translation_file.cpp msgid "Camera update toggle key" -msgstr "Tasto Attiva/Disattiva aggiornamento della camera." +msgstr "Tasto Attiva/Disattiva aggiornamento della camera" #: src/settings_translation_file.cpp msgid "Chat key" msgstr "Tasto Chat" #: src/settings_translation_file.cpp -#, fuzzy msgid "Chat toggle key" msgstr "Tasto mostra/nascondi chat" @@ -1366,7 +1363,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Client and Server" -msgstr "" +msgstr "Client e Server" #: src/settings_translation_file.cpp msgid "Climbing speed" @@ -1403,9 +1400,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Command key" -msgstr "Comando" +msgstr "Tasto del comando" #: src/settings_translation_file.cpp #, fuzzy @@ -1413,7 +1409,6 @@ msgid "Connect glass" msgstr "Vetro connesso" #: src/settings_translation_file.cpp -#, fuzzy msgid "Connect to external media server" msgstr "Connettiti al server dati esterno" @@ -1422,27 +1417,24 @@ msgid "Connects glass if supported by node." msgstr "Collega il vetro se supportato dal nodo." #: src/settings_translation_file.cpp -#, fuzzy msgid "Console alpha" -msgstr "Console" +msgstr "Console primaira" #: src/settings_translation_file.cpp -#, fuzzy msgid "Console color" -msgstr "Console" +msgstr "Colore della console" #: src/settings_translation_file.cpp -#, fuzzy msgid "Console key" -msgstr "Console" +msgstr "Tasto per la console" #: src/settings_translation_file.cpp msgid "Continuous forward" -msgstr "" +msgstr "Avanti automatico continuo" #: src/settings_translation_file.cpp msgid "Continuous forward movement (only used for testing)." -msgstr "" +msgstr "Movimento in avanti continuo (usato solo per i test)." #: src/settings_translation_file.cpp msgid "Controls" @@ -1454,12 +1446,17 @@ msgid "" "Examples: 72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays " "unchanged." msgstr "" +"Definisce la lunghezza del ciclo giorno/notte.\n" +"Ad esempio: 72 = 20min, 360 = 4min, 1 = 24ore, 0 =giorno e notte rimangono " +"fissi." #: src/settings_translation_file.cpp msgid "" "Controls size of deserts and beaches in Mapgen v6.\n" "When snowbiomes are enabled 'mgv6_freq_desert' is ignored." msgstr "" +"Definisce la dimensione di deserti e spiagge nel generatoe delle mappe v6.\n" +"Quando i biomi innevati sono abilitati 'mgv6_freq_desert' viene ignorato." #: src/settings_translation_file.cpp msgid "Crash message" @@ -1483,7 +1480,7 @@ msgstr "Colore del mirino (R,G,B)." #: src/settings_translation_file.cpp msgid "Crouch speed" -msgstr "" +msgstr "Velocita da accovacciato" #: src/settings_translation_file.cpp msgid "DPI" @@ -1495,7 +1492,7 @@ msgstr "Abilitare il danno" #: src/settings_translation_file.cpp msgid "Debug info toggle key" -msgstr "" +msgstr "Comando attiva/disattiva informazioni del debug" #: src/settings_translation_file.cpp msgid "Debug log level" @@ -1507,12 +1504,11 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Default acceleration" -msgstr "" +msgstr "Accelerazione di default" #: src/settings_translation_file.cpp -#, fuzzy msgid "Default game" -msgstr "modificare il gioco" +msgstr "Gioco di default" #: src/settings_translation_file.cpp msgid "" @@ -1521,9 +1517,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Default password" -msgstr "Nuova password" +msgstr "Password di default" #: src/settings_translation_file.cpp msgid "Default privileges" @@ -1576,9 +1571,8 @@ msgid "Detailed mod profiling" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Disable anticheat" -msgstr "Abilitare le particelle" +msgstr "Disattiva l'anticheat" #: src/settings_translation_file.cpp msgid "Disallow empty passwords" @@ -1589,14 +1583,13 @@ msgid "Domain name of server, to be displayed in the serverlist." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Double tap jump for fly" -msgstr "Volare On/Off = due volte \"saltare\"" +msgstr "Schiaccia due volte il tasto \"salto\" per volare" #: src/settings_translation_file.cpp -#, fuzzy msgid "Double-tapping the jump key toggles fly mode." -msgstr "Volare On/Off = due volte \"saltare\"" +msgstr "" +"Doppio click sul tasto \"salto\" per attivare/disattivare la modalità volo." #: src/settings_translation_file.cpp msgid "Drop item key" @@ -1674,9 +1667,8 @@ msgid "Enables caching of facedir rotated meshes." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Enables minimap." -msgstr "Abilitare il danno" +msgstr "Abilita la minimap." #: src/settings_translation_file.cpp msgid "" @@ -1706,12 +1698,11 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Fall bobbing" -msgstr "" +msgstr "Ondeggiamento visuale quando si cade" #: src/settings_translation_file.cpp -#, fuzzy msgid "Fallback font" -msgstr "needs_fallback_font" +msgstr "Fallback font" #: src/settings_translation_file.cpp msgid "Fallback font shadow" @@ -1770,9 +1761,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Filtering" -msgstr "Nessun Filtro" +msgstr "Filtraggio" #: src/settings_translation_file.cpp msgid "Fixed map seed" @@ -1819,7 +1809,6 @@ msgid "Font size" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Forward key" msgstr "Avanti" @@ -2015,9 +2004,8 @@ msgid "Ignore world errors" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "In-Game" -msgstr "Gioco" +msgstr "Nel gioco" #: src/settings_translation_file.cpp msgid "In-game chat console background alpha (opaqueness, between 0 and 255)." @@ -2036,7 +2024,6 @@ msgid "Interval of sending time of day to clients." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Inventory key" msgstr "Inventario" @@ -2099,9 +2086,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Jump key" -msgstr "Saltare" +msgstr "Salto" #: src/settings_translation_file.cpp msgid "Jumping speed" @@ -2333,9 +2319,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Left key" -msgstr "Menù a sinistra" +msgstr "Sinistra" #: src/settings_translation_file.cpp msgid "" @@ -2378,7 +2363,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Liquid fluidity smoothing" -msgstr "" +msgstr "Raffinatezza dello scorrere dei liquidi" #: src/settings_translation_file.cpp msgid "Liquid loop max" @@ -2390,7 +2375,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Liquid sink" -msgstr "" +msgstr "Velocità di caduta del liquiddi" #: src/settings_translation_file.cpp msgid "Liquid update interval in seconds." @@ -2405,14 +2390,12 @@ msgid "Main menu game manager" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Main menu mod manager" -msgstr "Menù principale" +msgstr "Pannello di controllo mod del menù principale" #: src/settings_translation_file.cpp -#, fuzzy msgid "Main menu script" -msgstr "Menù principale" +msgstr "Script del menù principale" #: src/settings_translation_file.cpp msgid "" @@ -2506,14 +2489,12 @@ msgid "Mapgen biome humidity noise parameters" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen debug" -msgstr "Generat. mappe" +msgstr "Debug del generatore delle mappe" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen flags" -msgstr "Generat. mappe" +msgstr "flags del generatore delle mappe" #: src/settings_translation_file.cpp #, fuzzy @@ -2594,14 +2575,12 @@ msgid "Mapgen heat blend noise parameters" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen name" -msgstr "Generat. mappe" +msgstr "Nome del genratore delle mappe" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen v5" -msgstr "Generat. mappe" +msgstr "Generatore mappe v5" #: src/settings_translation_file.cpp msgid "Mapgen v5 cave1 noise parameters" @@ -2624,9 +2603,8 @@ msgid "Mapgen v5 height noise parameters" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen v6" -msgstr "Generat. mappe" +msgstr "Generatore mappe v6" #: src/settings_translation_file.cpp msgid "Mapgen v6 apple trees noise parameters" @@ -2685,9 +2663,8 @@ msgid "Mapgen v6 trees noise parameters" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mapgen v7" -msgstr "Generat. mappe" +msgstr "Generatore mappe v7" #: src/settings_translation_file.cpp msgid "Mapgen v7 cave1 noise parameters" @@ -2816,7 +2793,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Maximum number of players that can connect simultaneously." -msgstr "" +msgstr "Numero di giocatori che si possono connettere simultaneamente." #: src/settings_translation_file.cpp msgid "Maximum number of statically stored objects in a block." @@ -2839,6 +2816,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Maximum time in ms a file download (e.g. a mod download) may take." msgstr "" +"Tempo massimo per il download di un file, ad esempio una mod, espresso in ms." #: src/settings_translation_file.cpp msgid "Maximum users" @@ -2849,7 +2827,6 @@ msgid "Maxmimum objects per block" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Menus" msgstr "Menù" @@ -2889,7 +2866,6 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Mipmapping" msgstr "Mip-Mapping" @@ -2982,7 +2958,6 @@ msgid "Noclip key" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Node highlighting" msgstr "Evidenziamento Nodi" @@ -3000,7 +2975,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Number of emerge threads" -msgstr "" +msgstr "Numero degli emerge threads" #: src/settings_translation_file.cpp msgid "" @@ -3010,6 +2985,11 @@ msgid "" "speed greatly\n" "at the cost of slightly buggy caves." msgstr "" +"Numero degli emerge threads da usare. Lascia questa voce vuota o aumenta " +"questo numero\n" +"per usare più di un thread. Su sistemi muliprocessore questo migliorerà " +"notevolmente la velocità della generazione delle mappe\n" +"ma potrebbe causare bug." #: src/settings_translation_file.cpp msgid "" @@ -3081,9 +3061,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Player name" -msgstr "Nome del giocatore troppo lungo." +msgstr "Nome del giocatore" #: src/settings_translation_file.cpp msgid "Player transfer distance" @@ -3091,7 +3070,7 @@ msgstr "" #: src/settings_translation_file.cpp msgid "Player versus Player" -msgstr "" +msgstr "PvP" #: src/settings_translation_file.cpp msgid "" @@ -3108,9 +3087,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Preload inventory textures" -msgstr "Caricamento..." +msgstr "Precaricamento delle textures dell'inventario" #: src/settings_translation_file.cpp msgid "Prevent mods from doing insecure things like running shell commands." @@ -3157,9 +3135,8 @@ msgid "Replaces the default main menu with a custom one." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Right key" -msgstr "Menù a destra" +msgstr "Destra" #: src/settings_translation_file.cpp msgid "Rightclick repetition interval" @@ -3199,9 +3176,8 @@ msgid "Screen width" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Screenshot" -msgstr "Istantanea" +msgstr "Istantanea schermo" #: src/settings_translation_file.cpp msgid "Screenshot folder" @@ -3228,32 +3204,26 @@ msgid "Selection box width" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server / Singleplayer" -msgstr "Giocatore singolo" +msgstr "Server / Giocatore singolo" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server URL" -msgstr "Server" +msgstr "URL del server" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server address" -msgstr "Porta del server" +msgstr "Indirizzo del server" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server description" -msgstr "Porta del server" +msgstr "Descrizione del server" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server name" -msgstr "Server" +msgstr "Nome del server" #: src/settings_translation_file.cpp -#, fuzzy msgid "Server port" msgstr "Porta del server" @@ -3321,9 +3291,8 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Smooth lighting" -msgstr "Illuminazione armoniosa" +msgstr "Raffinatezza ombreggiature" #: src/settings_translation_file.cpp msgid "" @@ -3340,9 +3309,8 @@ msgid "Smooths rotation of camera. 0 to disable." msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "Sneak key" -msgstr "Strisciare" +msgstr "Abbassati" #: src/settings_translation_file.cpp msgid "Sound" @@ -3530,9 +3498,8 @@ msgid "Use trilinear filtering when scaling textures." msgstr "Usa un filtro trilineare quando si scalano le texture." #: src/settings_translation_file.cpp -#, fuzzy msgid "Useful for mod developers." -msgstr "Sviluppatori principali" +msgstr "Utile per gli sviluppatori di mod." #: src/settings_translation_file.cpp msgid "V-Sync" @@ -3575,7 +3542,6 @@ msgid "Viewing range minimum" msgstr "Distanza minima di visibilità" #: src/settings_translation_file.cpp -#, fuzzy msgid "Volume" msgstr "Volume del suono" @@ -3640,7 +3606,6 @@ msgid "" msgstr "" #: src/settings_translation_file.cpp -#, fuzzy msgid "" "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n" "can be blurred, so automatically upscale them with nearest-neighbor\n" @@ -3722,7 +3687,6 @@ msgstr "" "premere F5)." #: src/settings_translation_file.cpp -#, fuzzy msgid "Width of the selectionbox's lines around nodes." msgstr "Larghezza dei riquadri attorno ai nodi." From 860d70bd0e228ee542e3e559961bfc7e56888d77 Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 28 Jan 2016 23:53:58 +0100 Subject: [PATCH 64/68] Don't print whole json data buffer to errorstream on error `errorstream` must not be overly verbose as clientside it is directly printed onto the ingame chat window. These days, the serverlist can contain > 200k bytes, so better print it to warningstream if the data buffer is too long. --- src/convert_json.cpp | 8 +++++++- src/script/lua_api/l_util.cpp | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/convert_json.cpp b/src/convert_json.cpp index e03508e21..e548c45f5 100644 --- a/src/convert_json.cpp +++ b/src/convert_json.cpp @@ -52,7 +52,13 @@ Json::Value fetchJsonValue(const std::string &url, if (!reader.parse(stream, root)) { errorstream << "URL: " << url << std::endl; errorstream << "Failed to parse json data " << reader.getFormattedErrorMessages(); - errorstream << "data: \"" << fetch_result.data << "\"" << std::endl; + if (fetch_result.data.size() > 100) { + errorstream << "Data (" << fetch_result.data.size() + << " bytes) printed to warningstream." << std::endl; + warningstream << "data: \"" << fetch_result.data << "\"" << std::endl; + } else { + errorstream << "data: \"" << fetch_result.data << "\"" << std::endl; + } return Json::Value(); } diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 3f7e15acf..39863b987 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -161,8 +161,14 @@ int ModApiUtil::l_parse_json(lua_State *L) if (!reader.parse(stream, root)) { errorstream << "Failed to parse json data " << reader.getFormattedErrorMessages(); - errorstream << "data: \"" << jsonstr << "\"" - << std::endl; + size_t jlen = strlen(jsonstr); + if (jlen > 100) { + errorstream << "Data (" << jlen + << " bytes) printed to warningstream." << std::endl; + warningstream << "data: \"" << jsonstr << "\"" << std::endl; + } else { + errorstream << "data: \"" << jsonstr << "\"" << std::endl; + } lua_pushnil(L); return 1; } From 4ac1e9bccbd0222ab779b3fc4d2144d60e1f2b49 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 23 Jan 2016 23:06:26 -0800 Subject: [PATCH 65/68] Clocksource: use a better clock if available. clock_gettime() is a far better clock than gettimeofday(). Even better than clock_gettime() is that you can select either CLOCK_MONOTONIC, or even CLOCK_MONOTONIC_RAW. These clocks offer high precision time. And the _RAW variant will never roll back due to NTP drift or daylight savings, or otherwise. I've adjusted this code to select the right clock method auto- matically based on what's available in the OS. This means that if you're running a very old linux version, MacOS or other, you will automatically get the best clocksource available. I've tested all Linux clocksources by selectively compiling and running a 10k+ timer test suite. In all cases I confirmed that the 3 POSIX Linux clocksources worked properly, and were selected properly. I've modified the OS X compile path to use the high-res clock source for all time functions, but I can't confirm it works or that it compiles. As for WIN32, I confirmed that the used clocksource is indeed a Monotonic clocksource, so good news: that code section appears to be exactly what it should be. --- doc/lua_api.txt | 2 +- src/porting.h | 69 +++++++++++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index e7c1b7dd5..7255852e0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1727,7 +1727,7 @@ Helper functions * `minetest.is_yes(arg)` * returns whether `arg` can be interpreted as yes * `minetest.get_us_time()` - * returns time with microsecond precision + * returns time with microsecond precision. May not return wall time. * `table.copy(table)`: returns a table * returns a deep copy of `table` diff --git a/src/porting.h b/src/porting.h index 5da32607c..5fe81a440 100644 --- a/src/porting.h +++ b/src/porting.h @@ -211,33 +211,11 @@ void initIrrlicht(irr::IrrlichtDevice * ); } #else // Posix - - inline u32 getTimeS() + inline void _os_get_clock(struct timespec *ts) { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec; - } - - inline u32 getTimeMs() - { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; - } - - inline u32 getTimeUs() - { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000 + tv.tv_usec; - } - - inline u32 getTimeNs() - { - struct timespec ts; - // from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x -#if defined(__MACH__) && defined(__APPLE__) // OS X does not have clock_gettime, use clock_get_time +#if defined(__MACH__) && defined(__APPLE__) + // from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x + // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); @@ -245,9 +223,44 @@ void initIrrlicht(irr::IrrlichtDevice * ); mach_port_deallocate(mach_task_self(), cclock); ts.tv_sec = mts.tv_sec; ts.tv_nsec = mts.tv_nsec; +#elif defined(CLOCK_MONOTONIC_RAW) + clock_gettime(CLOCK_MONOTONIC_RAW, ts); +#elif defined(_POSIX_MONOTONIC_CLOCK) + clock_gettime(CLOCK_MONOTONIC, ts); #else - clock_gettime(CLOCK_REALTIME, &ts); -#endif + struct timeval tv; + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, ts); +#endif // defined(__MACH__) && defined(__APPLE__) + } + + // Note: these clock functions do not return wall time, but + // generally a clock that starts at 0 when the process starts. + inline u32 getTimeS() + { + struct timespec ts; + _os_get_clock(&ts); + return ts.tv_sec; + } + + inline u32 getTimeMs() + { + struct timespec ts; + _os_get_clock(&ts); + return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + } + + inline u32 getTimeUs() + { + struct timespec ts; + _os_get_clock(&ts); + return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + } + + inline u32 getTimeNs() + { + struct timespec ts; + _os_get_clock(&ts); return ts.tv_sec * 1000000000 + ts.tv_nsec; } From ad884f23d4e73d38ce0f529de49591dd66cee44d Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Jan 2016 01:07:38 -0800 Subject: [PATCH 66/68] New timer design. I could honestly not make much sense of the timer implementation that was here. Instead I've implemented the type of timer algorithm that I've used before, and tested it instead. The concept is extremely simple: all timers are put in an ordered list. We check every server tick if any of the timers have elapsed, and execute the function associated with this timer. We know that many timers by themselves cause new timers to be added to this list, so we iterate *backwards* over the timer list. This means that new timers being added while timers are being executed, can never be executed in the same function pass, as they are always appended to the table *after* the end of the table, which we will never reach in the current pass over all the table elements. We switch time keeping to minetest.get_us_time(). dtime is likely unreliable and we have our own high-res timer that we can fix if it is indeed broken. This removes the need to do any sort of time keeping. --- builtin/game/misc.lua | 98 ++++++++++++++++--------------------------- doc/lua_api.txt | 2 +- 2 files changed, 37 insertions(+), 63 deletions(-) diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index efd0f8dc7..bacadf18f 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -4,74 +4,48 @@ -- Misc. API functions -- -local timers = {} -local mintime -local function update_timers(delay) - mintime = false - local sub = 0 - for index = 1, #timers do - index = index - sub - local timer = timers[index] - timer.time = timer.time - delay - if timer.time <= 0 then - core.set_last_run_mod(timer.mod_origin) - timer.func(unpack(timer.args or {})) - table.remove(timers, index) - sub = sub + 1 - elseif mintime then - mintime = math.min(mintime, timer.time) - else - mintime = timer.time +local jobs = {} +local time = 0.0 +local last = 0.0 + +core.register_globalstep(function(dtime) + local new = core.get_us_time() / 1000000 + if new > last then + time = time + (new - last) + else + -- Overflow, we may lose a little bit of time here but + -- only 1 tick max, potentially running timers slightly + -- too early. + time = time + new + end + last = new + + if #jobs < 1 then + return + end + + -- Iterate backwards so that we miss any new timers added by + -- a timer callback, and so that we don't skip the next timer + -- in the list if we remove one. + for i = #jobs, 1, -1 do + local job = jobs[i] + if time >= job.expire then + core.set_last_run_mod(job.mod_origin) + job.func(unpack(job.arg)) + table.remove(jobs, i) end end -end - -local timers_to_add -local function add_timers() - for _, timer in ipairs(timers_to_add) do - table.insert(timers, timer) - end - timers_to_add = false -end - -local delay = 0 -core.register_globalstep(function(dtime) - if not mintime then - -- abort if no timers are running - return - end - if timers_to_add then - add_timers() - end - delay = delay + dtime - if delay < mintime then - return - end - update_timers(delay) - delay = 0 end) -function core.after(time, func, ...) +function core.after(after, func, ...) assert(tonumber(time) and type(func) == "function", "Invalid core.after invocation") - if not mintime then - mintime = time - timers_to_add = {{ - time = time+delay, - func = func, - args = {...}, - mod_origin = core.get_last_run_mod(), - }} - return - end - mintime = math.min(mintime, time) - timers_to_add = timers_to_add or {} - timers_to_add[#timers_to_add+1] = { - time = time+delay, - func = func, - args = {...}, - mod_origin = core.get_last_run_mod(), - } + table.insert(jobs, { + func = func, + expire = time + after, + arg = {...}, + mod_origin = core.get_last_run_mod() + }) end function core.check_player_privs(player_or_name, ...) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7255852e0..b6bc957c1 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2242,7 +2242,7 @@ These functions return the leftover itemstack. ### Timing * `minetest.after(time, func, ...)` - * Call the function `func` after `time` seconds + * Call the function `func` after `time` seconds, may be fractional * Optional: Variable number of arguments that are passed to `func` ### Server From 4e93ba06a749fa2503786bf8d7dbda3d1e36a65a Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 25 Jan 2016 00:06:01 +0100 Subject: [PATCH 67/68] Don't pass non-const references to collision methods Non const references cause a lot of confusion with behaviour of code, and are disallowed by minetest style guide. --- src/collision.cpp | 154 +++++++++++++++----------------- src/collision.h | 6 +- src/content_cao.cpp | 4 +- src/content_sao.cpp | 2 +- src/localplayer.cpp | 4 +- src/particles.cpp | 4 +- src/unittest/test_collision.cpp | 32 +++---- 7 files changed, 98 insertions(+), 108 deletions(-) diff --git a/src/collision.cpp b/src/collision.cpp index 187df0a5d..2ae59b38f 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., // The time after which the collision occurs is stored in dtime. int axisAlignedCollision( const aabb3f &staticbox, const aabb3f &movingbox, - const v3f &speed, f32 d, f32 &dtime) + const v3f &speed, f32 d, f32 *dtime) { //TimeTaker tt("axisAlignedCollision"); @@ -59,13 +59,12 @@ int axisAlignedCollision( if(speed.X > 0) // Check for collision with X- plane { - if(relbox.MaxEdge.X <= d) - { - dtime = - relbox.MaxEdge.X / speed.X; - if((relbox.MinEdge.Y + speed.Y * dtime < ysize) && - (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO) && - (relbox.MinEdge.Z + speed.Z * dtime < zsize) && - (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO)) + if (relbox.MaxEdge.X <= d) { + *dtime = -relbox.MaxEdge.X / speed.X; + if ((relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && + (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && + (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) return 0; } else if(relbox.MinEdge.X > xsize) @@ -75,13 +74,12 @@ int axisAlignedCollision( } else if(speed.X < 0) // Check for collision with X+ plane { - if(relbox.MinEdge.X >= xsize - d) - { - dtime = (xsize - relbox.MinEdge.X) / speed.X; - if((relbox.MinEdge.Y + speed.Y * dtime < ysize) && - (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO) && - (relbox.MinEdge.Z + speed.Z * dtime < zsize) && - (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO)) + if (relbox.MinEdge.X >= xsize - d) { + *dtime = (xsize - relbox.MinEdge.X) / speed.X; + if ((relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && + (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && + (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) return 0; } else if(relbox.MaxEdge.X < 0) @@ -94,13 +92,12 @@ int axisAlignedCollision( if(speed.Y > 0) // Check for collision with Y- plane { - if(relbox.MaxEdge.Y <= d) - { - dtime = - relbox.MaxEdge.Y / speed.Y; - if((relbox.MinEdge.X + speed.X * dtime < xsize) && - (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) && - (relbox.MinEdge.Z + speed.Z * dtime < zsize) && - (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO)) + if (relbox.MaxEdge.Y <= d) { + *dtime = -relbox.MaxEdge.Y / speed.Y; + if ((relbox.MinEdge.X + speed.X * (*dtime) < xsize) && + (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && + (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) return 1; } else if(relbox.MinEdge.Y > ysize) @@ -110,13 +107,12 @@ int axisAlignedCollision( } else if(speed.Y < 0) // Check for collision with Y+ plane { - if(relbox.MinEdge.Y >= ysize - d) - { - dtime = (ysize - relbox.MinEdge.Y) / speed.Y; - if((relbox.MinEdge.X + speed.X * dtime < xsize) && - (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) && - (relbox.MinEdge.Z + speed.Z * dtime < zsize) && - (relbox.MaxEdge.Z + speed.Z * dtime > COLL_ZERO)) + if (relbox.MinEdge.Y >= ysize - d) { + *dtime = (ysize - relbox.MinEdge.Y) / speed.Y; + if ((relbox.MinEdge.X + speed.X * (*dtime) < xsize) && + (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && + (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) return 1; } else if(relbox.MaxEdge.Y < 0) @@ -129,13 +125,12 @@ int axisAlignedCollision( if(speed.Z > 0) // Check for collision with Z- plane { - if(relbox.MaxEdge.Z <= d) - { - dtime = - relbox.MaxEdge.Z / speed.Z; - if((relbox.MinEdge.X + speed.X * dtime < xsize) && - (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) && - (relbox.MinEdge.Y + speed.Y * dtime < ysize) && - (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO)) + if (relbox.MaxEdge.Z <= d) { + *dtime = -relbox.MaxEdge.Z / speed.Z; + if ((relbox.MinEdge.X + speed.X * (*dtime) < xsize) && + (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && + (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO)) return 2; } //else if(relbox.MinEdge.Z > zsize) @@ -145,13 +140,12 @@ int axisAlignedCollision( } else if(speed.Z < 0) // Check for collision with Z+ plane { - if(relbox.MinEdge.Z >= zsize - d) - { - dtime = (zsize - relbox.MinEdge.Z) / speed.Z; - if((relbox.MinEdge.X + speed.X * dtime < xsize) && - (relbox.MaxEdge.X + speed.X * dtime > COLL_ZERO) && - (relbox.MinEdge.Y + speed.Y * dtime < ysize) && - (relbox.MaxEdge.Y + speed.Y * dtime > COLL_ZERO)) + if (relbox.MinEdge.Z >= zsize - d) { + *dtime = (zsize - relbox.MinEdge.Z) / speed.Z; + if ((relbox.MinEdge.X + speed.X * (*dtime) < xsize) && + (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && + (relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && + (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO)) return 2; } //else if(relbox.MaxEdge.Z < 0) @@ -195,8 +189,8 @@ bool wouldCollideWithCeiling( collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, - v3f &pos_f, v3f &speed_f, - v3f &accel_f,ActiveObject* self, + v3f *pos_f, v3f *speed_f, + v3f accel_f, ActiveObject *self, bool collideWithObjects) { static bool time_notification_done = false; @@ -219,16 +213,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, } else { time_notification_done = false; } - speed_f += accel_f * dtime; + *speed_f += accel_f * dtime; // If there is no speed, there are no collisions - if(speed_f.getLength() == 0) + if (speed_f->getLength() == 0) return result; // Limit speed for avoiding hangs - speed_f.Y=rangelim(speed_f.Y,-5000,5000); - speed_f.X=rangelim(speed_f.X,-5000,5000); - speed_f.Z=rangelim(speed_f.Z,-5000,5000); + speed_f->Y = rangelim(speed_f->Y, -5000, 5000); + speed_f->X = rangelim(speed_f->X, -5000, 5000); + speed_f->Z = rangelim(speed_f->Z, -5000, 5000); /* Collect node boxes in movement range @@ -243,8 +237,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, //TimeTaker tt2("collisionMoveSimple collect boxes"); ScopeProfiler sp(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG); - v3s16 oldpos_i = floatToInt(pos_f, BS); - v3s16 newpos_i = floatToInt(pos_f + speed_f * dtime, BS); + v3s16 oldpos_i = floatToInt(*pos_f, BS); + v3s16 newpos_i = floatToInt(*pos_f + *speed_f * dtime, BS); s16 min_x = MYMIN(oldpos_i.X, newpos_i.X) + (box_0.MinEdge.X / BS) - 1; s16 min_y = MYMIN(oldpos_i.Y, newpos_i.Y) + (box_0.MinEdge.Y / BS) - 1; s16 min_z = MYMIN(oldpos_i.Z, newpos_i.Z) + (box_0.MinEdge.Z / BS) - 1; @@ -318,9 +312,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, #ifndef SERVER ClientEnvironment *c_env = dynamic_cast(env); if (c_env != 0) { - f32 distance = speed_f.getLength(); + f32 distance = speed_f->getLength(); std::vector clientobjects; - c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects); + c_env->getActiveObjects(*pos_f, distance * 1.5, clientobjects); for (size_t i=0; i < clientobjects.size(); i++) { if ((self == 0) || (self != clientobjects[i].obj)) { objects.push_back((ActiveObject*)clientobjects[i].obj); @@ -332,9 +326,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, { ServerEnvironment *s_env = dynamic_cast(env); if (s_env != 0) { - f32 distance = speed_f.getLength(); + f32 distance = speed_f->getLength(); std::vector s_objects; - s_env->getObjectsInsideRadius(s_objects, pos_f, distance * 1.5); + s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5); for (std::vector::iterator iter = s_objects.begin(); iter != s_objects.end(); ++iter) { ServerActiveObject *current = s_env->getActiveObject(*iter); if ((self == 0) || (self != current)) { @@ -399,8 +393,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, } aabb3f movingbox = box_0; - movingbox.MinEdge += pos_f; - movingbox.MaxEdge += pos_f; + movingbox.MinEdge += *pos_f; + movingbox.MaxEdge += *pos_f; int nearest_collided = -1; f32 nearest_dtime = dtime; @@ -417,7 +411,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, // Find nearest collision of the two boxes (raytracing-like) f32 dtime_tmp; int collided = axisAlignedCollision( - cboxes[boxindex], movingbox, speed_f, d, dtime_tmp); + cboxes[boxindex], movingbox, *speed_f, d, &dtime_tmp); if (collided == -1 || dtime_tmp >= nearest_dtime) continue; @@ -429,7 +423,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, if (nearest_collided == -1) { // No collision with any collision box. - pos_f += speed_f * dtime; + *pos_f += *speed_f * dtime; dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers } else { // Otherwise, a collision occurred. @@ -452,14 +446,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, // Handle negative nearest_dtime (can be caused by the d allowance) if (!step_up) { if (nearest_collided == 0) - pos_f.X += speed_f.X * nearest_dtime; + pos_f->X += speed_f->X * nearest_dtime; if (nearest_collided == 1) - pos_f.Y += speed_f.Y * nearest_dtime; + pos_f->Y += speed_f->Y * nearest_dtime; if (nearest_collided == 2) - pos_f.Z += speed_f.Z * nearest_dtime; + pos_f->Z += speed_f->Z * nearest_dtime; } } else { - pos_f += speed_f * nearest_dtime; + *pos_f += *speed_f * nearest_dtime; dtime -= nearest_dtime; } @@ -475,7 +469,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, info.node_p = node_positions[nearest_boxindex]; info.bouncy = bouncy; - info.old_speed = speed_f; + info.old_speed = *speed_f; // Set the speed component that caused the collision to zero if (step_up) { @@ -483,29 +477,29 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, is_step_up[nearest_boxindex] = true; is_collision = false; } else if(nearest_collided == 0) { // X - if (fabs(speed_f.X) > BS * 3) - speed_f.X *= bounce; + if (fabs(speed_f->X) > BS * 3) + speed_f->X *= bounce; else - speed_f.X = 0; + speed_f->X = 0; result.collides = true; result.collides_xz = true; } else if(nearest_collided == 1) { // Y - if(fabs(speed_f.Y) > BS * 3) - speed_f.Y *= bounce; + if (fabs(speed_f->Y) > BS * 3) + speed_f->Y *= bounce; else - speed_f.Y = 0; + speed_f->Y = 0; result.collides = true; } else if(nearest_collided == 2) { // Z - if (fabs(speed_f.Z) > BS * 3) - speed_f.Z *= bounce; + if (fabs(speed_f->Z) > BS * 3) + speed_f->Z *= bounce; else - speed_f.Z = 0; + speed_f->Z = 0; result.collides = true; result.collides_xz = true; } - info.new_speed = speed_f; + info.new_speed = *speed_f; if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1 * BS) is_collision = false; @@ -519,8 +513,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, Final touches: Check if standing on ground, step up stairs. */ aabb3f box = box_0; - box.MinEdge += pos_f; - box.MaxEdge += pos_f; + box.MinEdge += *pos_f; + box.MaxEdge += *pos_f; for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) { const aabb3f& cbox = cboxes[boxindex]; @@ -537,10 +531,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, cbox.MaxEdge.Z - d > box.MinEdge.Z && cbox.MinEdge.Z + d < box.MaxEdge.Z) { if (is_step_up[boxindex]) { - pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y); + pos_f->Y += (cbox.MaxEdge.Y - box.MinEdge.Y); box = box_0; - box.MinEdge += pos_f; - box.MaxEdge += pos_f; + box.MinEdge += *pos_f; + box.MaxEdge += *pos_f; } if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) { result.touching_ground = true; diff --git a/src/collision.h b/src/collision.h index d1234bef3..1ceaba81c 100644 --- a/src/collision.h +++ b/src/collision.h @@ -73,8 +73,8 @@ struct collisionMoveResult collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, - v3f &pos_f, v3f &speed_f, - v3f &accel_f,ActiveObject* self=0, + v3f *pos_f, v3f *speed_f, + v3f accel_f, ActiveObject *self=NULL, bool collideWithObjects=true); // Helper function: @@ -83,7 +83,7 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef, // dtime receives time until first collision, invalid if -1 is returned int axisAlignedCollision( const aabb3f &staticbox, const aabb3f &movingbox, - const v3f &speed, f32 d, f32 &dtime); + const v3f &speed, f32 d, f32 *dtime); // Helper function: // Checks if moving the movingbox up by the given distance would hit a ceiling. diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 1b8e84c8f..c3247bd17 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1192,15 +1192,13 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) f32 pos_max_d = BS*0.125; // Distance per iteration v3f p_pos = m_position; v3f p_velocity = m_velocity; - v3f p_acceleration = m_acceleration; moveresult = collisionMoveSimple(env,env->getGameDef(), pos_max_d, box, m_prop.stepheight, dtime, - p_pos, p_velocity, p_acceleration, + &p_pos, &p_velocity, m_acceleration, this, m_prop.collideWithObjects); // Apply results m_position = p_pos; m_velocity = p_velocity; - m_acceleration = p_acceleration; bool is_end_position = moveresult.collides; pos_translator.update(m_position, is_end_position, dtime); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 4d144aa17..fa2454821 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -269,7 +269,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) v3f p_acceleration = m_acceleration; moveresult = collisionMoveSimple(m_env,m_env->getGameDef(), pos_max_d, box, m_prop.stepheight, dtime, - p_pos, p_velocity, p_acceleration, + &p_pos, &p_velocity, p_acceleration, this, m_prop.collideWithObjects); // Apply results diff --git a/src/localplayer.cpp b/src/localplayer.cpp index fd781f940..60aec95d4 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -214,8 +214,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, v3f accel_f = v3f(0,0,0); collisionMoveResult result = collisionMoveSimple(env, m_gamedef, - pos_max_d, m_collisionbox, player_stepheight, dtime, - position, m_speed, accel_f); + pos_max_d, m_collisionbox, player_stepheight, dtime, + &position, &m_speed, accel_f); /* If the player's feet touch the topside of any node, this is diff --git a/src/particles.cpp b/src/particles.cpp index ebb54a49a..8150e19ac 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -131,14 +131,12 @@ void Particle::step(float dtime) core::aabbox3d box = m_collisionbox; v3f p_pos = m_pos*BS; v3f p_velocity = m_velocity*BS; - v3f p_acceleration = m_acceleration*BS; collisionMoveSimple(m_env, m_gamedef, BS*0.5, box, 0, dtime, - p_pos, p_velocity, p_acceleration); + &p_pos, &p_velocity, m_acceleration * BS); m_pos = p_pos/BS; m_velocity = p_velocity/BS; - m_acceleration = p_acceleration/BS; } else { diff --git a/src/unittest/test_collision.cpp b/src/unittest/test_collision.cpp index e505de450..332d3fa13 100644 --- a/src/unittest/test_collision.cpp +++ b/src/unittest/test_collision.cpp @@ -51,7 +51,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-2, by, bz, bx-1, by+1, bz+1); v3f v(1, 0, 0); f32 dtime = 0; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 1.000) < 0.001); } { @@ -59,21 +59,21 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-2, by, bz, bx-1, by+1, bz+1); v3f v(-1, 0, 0); f32 dtime = 0; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == -1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == -1); } { aabb3f s(bx, by, bz, bx+1, by+1, bz+1); aabb3f m(bx-2, by+1.5, bz, bx-1, by+2.5, bz-1); v3f v(1, 0, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == -1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == -1); } { aabb3f s(bx, by, bz, bx+1, by+1, bz+1); aabb3f m(bx-2, by-1.5, bz, bx-1.5, by+0.5, bz+1); v3f v(0.5, 0.1, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 3.000) < 0.001); } { @@ -81,7 +81,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-2, by-1.5, bz, bx-1.5, by+0.5, bz+1); v3f v(0.5, 0.1, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 3.000) < 0.001); } @@ -91,7 +91,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2, by, bz, bx+3, by+1, bz+1); v3f v(-1, 0, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 1.000) < 0.001); } { @@ -99,21 +99,21 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2, by, bz, bx+3, by+1, bz+1); v3f v(1, 0, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == -1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == -1); } { aabb3f s(bx, by, bz, bx+1, by+1, bz+1); aabb3f m(bx+2, by, bz+1.5, bx+3, by+1, bz+3.5); v3f v(-1, 0, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == -1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == -1); } { aabb3f s(bx, by, bz, bx+1, by+1, bz+1); aabb3f m(bx+2, by-1.5, bz, bx+2.5, by-0.5, bz+1); v3f v(-0.5, 0.2, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 1); // Y, not X! + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 1); // Y, not X! UASSERT(fabs(dtime - 2.500) < 0.001); } { @@ -121,7 +121,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2, by-1.5, bz, bx+2.5, by-0.5, bz+1); v3f v(-0.5, 0.3, 0); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 2.000) < 0.001); } @@ -133,7 +133,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2.3, by+2.29, bz+2.29, bx+4.2, by+4.2, bz+4.2); v3f v(-1./3, -1./3, -1./3); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 0.9) < 0.001); } { @@ -141,7 +141,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2.29, by+2.3, bz+2.29, bx+4.2, by+4.2, bz+4.2); v3f v(-1./3, -1./3, -1./3); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 1); UASSERT(fabs(dtime - 0.9) < 0.001); } { @@ -149,7 +149,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx+2.29, by+2.29, bz+2.3, bx+4.2, by+4.2, bz+4.2); v3f v(-1./3, -1./3, -1./3); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 2); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 2); UASSERT(fabs(dtime - 0.9) < 0.001); } { @@ -157,7 +157,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.3, by-2.29, bz-2.29); v3f v(1./7, 1./7, 1./7); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 0); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 0); UASSERT(fabs(dtime - 16.1) < 0.001); } { @@ -165,7 +165,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.29, by-2.3, bz-2.29); v3f v(1./7, 1./7, 1./7); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 1); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 1); UASSERT(fabs(dtime - 16.1) < 0.001); } { @@ -173,7 +173,7 @@ void TestCollision::testAxisAlignedCollision() aabb3f m(bx-4.2, by-4.2, bz-4.2, bx-2.29, by-2.29, bz-2.3); v3f v(1./7, 1./7, 1./7); f32 dtime; - UASSERT(axisAlignedCollision(s, m, v, 0, dtime) == 2); + UASSERT(axisAlignedCollision(s, m, v, 0, &dtime) == 2); UASSERT(fabs(dtime - 16.1) < 0.001); } } From 83583aa2d5f795ede066ab7f8e28162633d3786a Mon Sep 17 00:00:00 2001 From: Pavel Puchkin Date: Fri, 29 Jan 2016 16:43:29 +0200 Subject: [PATCH 68/68] Fix OSX building issue caused by ad884f2 --- src/porting.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/porting.h b/src/porting.h index 5fe81a440..4d51c5058 100644 --- a/src/porting.h +++ b/src/porting.h @@ -221,8 +221,8 @@ void initIrrlicht(irr::IrrlichtDevice * ); host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; + ts->tv_sec = mts.tv_sec; + ts->tv_nsec = mts.tv_nsec; #elif defined(CLOCK_MONOTONIC_RAW) clock_gettime(CLOCK_MONOTONIC_RAW, ts); #elif defined(_POSIX_MONOTONIC_CLOCK)