summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt88
-rw-r--r--src/client.cpp1
-rw-r--r--src/cmake_config.h.in4
-rw-r--r--src/config.h11
-rw-r--r--src/gettext.h28
-rw-r--r--src/guiKeyChangeMenu.cpp84
-rw-r--r--src/guiKeyChangeMenu.h35
-rw-r--r--src/guiMainMenu.cpp6
-rw-r--r--src/guiMessageMenu.cpp2
-rw-r--r--src/guiPasswordChange.cpp8
-rw-r--r--src/guiPauseMenu.cpp4
-rw-r--r--src/guiTextInputMenu.cpp2
-rw-r--r--src/keycode.cpp1
-rw-r--r--src/main.cpp8
-rw-r--r--src/map.cpp423
-rw-r--r--src/mapnode.h7
-rw-r--r--src/servermain.cpp2
17 files changed, 370 insertions, 344 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4d51f7104..32177f8a9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,15 +1,19 @@
+project(minetest-delta)
cmake_minimum_required( VERSION 2.6 )
-project(minetest)
-
if(RUN_IN_PLACE)
add_definitions ( -DRUN_IN_PLACE )
endif(RUN_IN_PLACE)
-OPTION(USE_GETTEXT "Use GetText for internationalization" OFF)
+# user-visible option to enable/disable gettext usage
+OPTION(ENABLE_GETTEXT "Use GetText for internationalization" ON)
+
+# this is only set to 1 if gettext is enabled _and_ available
+set(USE_GETTEXT 0)
-if(USE_GETTEXT)
- find_package(GettextLib REQUIRED)
+find_package(GettextLib)
+
+if(GETTEXT_FOUND AND ENABLE_GETTEXT)
message(STATUS "gettext include path: ${GETTEXT_INCLUDE_DIR}")
message(STATUS "gettext msgfmt path: ${GETTEXT_MSGFMT}")
if(WIN32)
@@ -17,16 +21,13 @@ if(USE_GETTEXT)
message(STATUS "gettext dll: ${GETTEXT_DLL}")
message(STATUS "gettext iconv dll: ${GETTEXT_ICONV_DLL}")
endif()
- if (GETTEXT_FOUND)
- add_definitions( -DUSE_GETTEXT )
- message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}")
- else()
- message(STATUS "ERROR: GetText enabled but not found, disabling")
- set(USE_GETTEXT FALSE)
- endif(GETTEXT_FOUND)
-else(USE_GETTEXT)
+ set(USE_GETTEXT 1)
+ message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}")
+elseif(GETTEXT_FOUND AND NOT ENABLE_GETTEXT)
+ MESSAGE(STATUS "GetText found but disabled;")
+else(GETTEXT_FOUND AND ENABLE_GETTEXT)
message(STATUS "GetText disabled")
-endif(USE_GETTEXT)
+endif(GETTEXT_FOUND AND ENABLE_GETTEXT)
if(NOT MSVC)
set(USE_GPROF 0 CACHE BOOL "Use -pg flag for g++")
@@ -274,7 +275,7 @@ if(BUILD_CLIENT)
install(FILES ${images} DESTINATION ${DATADIR})
- if (USE_GETTEXT)
+ if(USE_GETTEXT)
foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
set(MO_BUILD_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
@@ -305,54 +306,29 @@ if(BUILD_SERVER)
endif(BUILD_SERVER)
if (USE_GETTEXT)
- add_custom_command(OUTPUT "${GETTEXT_PO_PATH}/en"
- COMMAND ${CMAKE_COMMAND} -E make_directory "${GETTEXT_PO_PATH}/en"
- COMMENT "po-update [en]: creating translation template base directory")
- set(POT_FILE "${GETTEXT_PO_PATH}/en/minetest.pot")
- file(GLOB GETTEXT_POT_DEPS *.cpp *.h)
- file(GLOB GETTEXT_POT_DEPS_REL RELATIVE ${CMAKE_SOURCE_DIR} *.cpp *.h)
- add_custom_command(OUTPUT ${POT_FILE}
- COMMAND ${GETTEXT_EXTRACT} -F -n -o ${POT_FILE} ${GETTEXT_POT_DEPS_REL}
- DEPENDS "${GETTEXT_PO_PATH}/en" ${GETTEXT_POT_DEPS}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMENT "po-update [en]: updating translation template")
-
- set(PO_FILES)
set(MO_FILES)
foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
- # skip the 'en' locale which is treated separately
- if (NOT LOCALE STREQUAL "en")
- set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/minetest.po")
- add_custom_command(OUTPUT ${PO_FILE_PATH}
- COMMAND ${GETTEXT_MSGMERGE} -F -U ${PO_FILE_PATH} ${POT_FILE}
- DEPENDS ${POT_FILE}
- WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
- COMMENT "po-update [${LOCALE}]: updating strings")
-
+ set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/minetest.po")
+ set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
+ set(MO_FILE_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
+
+ add_custom_command(OUTPUT ${MO_BUILD_PATH}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH}
+ COMMENT "mo-update [${LOCALE}]: Creating locale directory.")
+
+ add_custom_command(
+ OUTPUT ${MO_FILE_PATH}
+ COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH}
+ DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH}
+ WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
+ COMMENT "mo-update [${LOCALE}]: Creating mo file."
+ )
- set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
- add_custom_command(OUTPUT ${MO_BUILD_PATH}
- COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH}
- COMMENT "mo-update [${LOCALE}]: Creating locale directory.")
-
- set(MO_FILE_PATH "${MO_BUILD_PATH}/minetest.mo")
-
- add_custom_command(
- OUTPUT ${MO_FILE_PATH}
- COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH}
- DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH}
- WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
- COMMENT "mo-update [${LOCALE}]: Creating mo file."
- )
-
- set(MO_FILES ${MO_FILES} ${MO_FILE_PATH})
- set(PO_FILES ${PO_FILES} ${PO_FILE_PATH})
- endif(NOT LOCALE STREQUAL "en")
+ set(MO_FILES ${MO_FILES} ${MO_FILE_PATH})
endforeach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES})
- add_custom_target(updatepo COMMENT "po update" DEPENDS ${PO_FILES})
endif(USE_GETTEXT)
# Subdirectories
diff --git a/src/client.cpp b/src/client.cpp
index 55f0af6dc..02f78e233 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -936,7 +936,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
*/
//m_env.getClientMap().updateMeshes(block->getPos(), getDayNightRatio());
-
/*
Add it to mesh update queue and set it to be acknowledged after update.
*/
diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in
index 5e375191f..7cbb11f6b 100644
--- a/src/cmake_config.h.in
+++ b/src/cmake_config.h.in
@@ -3,14 +3,16 @@
#ifndef CMAKE_CONFIG_H
#define CMAKE_CONFIG_H
+#define PROJECT_NAME "@PROJECT_NAME@"
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#define VERSION_STRING "@VERSION_STRING@"
+#define USE_GETTEXT @USE_GETTEXT@
#ifdef NDEBUG
#define BUILD_TYPE "Release"
#else
#define BUILD_TYPE "Debug"
#endif
-#define BUILD_INFO "VER="VERSION_STRING" RUN_IN_PLACE=@RUN_IN_PLACE@ INSTALL_PREFIX=@CMAKE_INSTALL_PREFIX@ BUILD_TYPE="BUILD_TYPE
+#define BUILD_INFO "VER="VERSION_STRING" RUN_IN_PLACE=@RUN_IN_PLACE@ USE_GETTEXT=@USE_GETTEXT@ INSTALL_PREFIX=@CMAKE_INSTALL_PREFIX@ BUILD_TYPE="BUILD_TYPE
#endif
diff --git a/src/config.h b/src/config.h
index b24cf6a69..54b89a060 100644
--- a/src/config.h
+++ b/src/config.h
@@ -9,6 +9,8 @@
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
#else
+ #define PROJECT_NAME "minetest"
+
//#define INSTALL_PREFIX ""
#define VERSION_STRING "unknown"
#ifdef NDEBUG
@@ -21,8 +23,13 @@
#else
#define RUN_IN_PLACE_BOOLSTRING "0"
#endif
- #define BUILD_INFO "NON-CMAKE RUN_IN_PLACE="RUN_IN_PLACE_BOOLSTRING" BUILD_TYPE="BUILD_TYPE
-#endif
+ #if USE_GETTEXT
+ #define USE_GETTEXT_BOOLSTRING "1"
+ #else
+ #define USE_GETTEXT_BOOLSTRING "0"
+ #endif
+ #define BUILD_INFO "NON-CMAKE RUN_IN_PLACE="RUN_IN_PLACE_BOOLSTRING" USE_GETTEXT="USE_GETTEXT_BOOLSTRING" BUILD_TYPE="BUILD_TYPE
+#endif
#endif
diff --git a/src/gettext.h b/src/gettext.h
index 73b9f8986..ff3a0f8cb 100644
--- a/src/gettext.h
+++ b/src/gettext.h
@@ -1,4 +1,7 @@
-#ifdef USE_GETTEXT
+#ifndef GETTEXT_HEADER
+#include "config.h" // for USE_GETTEXT
+
+#if USE_GETTEXT
#include <libintl.h>
#else
#define gettext(String) String
@@ -8,6 +11,17 @@
#define gettext_noop(String) String
#define N_(String) gettext_noop (String)
+inline void init_gettext(const char *path) {
+#if USE_GETTEXT
+ // don't do this if MSVC compiler is used, it gives an assertion fail
+ #ifndef _MSC_VER
+ setlocale(LC_MESSAGES, "");
+ #endif
+ bindtextdomain(PROJECT_NAME, path);
+ textdomain(PROJECT_NAME);
+#endif
+}
+
inline wchar_t* chartowchar_t(const char *str)
{
size_t l = strlen(str)+1;
@@ -15,3 +29,15 @@ inline wchar_t* chartowchar_t(const char *str)
mbstowcs(nstr, str, l);
return nstr;
}
+
+inline void changeCtype(const char *l)
+{
+ char *ret = NULL;
+ ret = setlocale(LC_CTYPE, l);
+ if(ret == NULL)
+ std::cout<<"locale could not be set"<<std::endl;
+ else
+ std::cout<<"locale has been set to:"<<ret<<std::endl;
+}
+#define GETTEXT_HEADER
+#endif
diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp
index 98d6f8086..7855751ff 100644
--- a/src/guiKeyChangeMenu.cpp
+++ b/src/guiKeyChangeMenu.cpp
@@ -80,9 +80,9 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 125, 20);
rect += topleft + v2s32(25, 3);
- const wchar_t *text = L"KEYBINDINGS";
//gui::IGUIStaticText *t =
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("KEYBINDINGS")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
v2s32 offset(25, 40);
@@ -91,8 +91,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Forward";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Forward")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -108,8 +108,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Backward";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Backward")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -124,8 +124,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Left";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Left")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -139,8 +139,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Right";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Right")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -155,8 +155,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Use";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Use")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -170,8 +170,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Sneak";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Sneak")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -186,8 +186,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Jump";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Jump")), rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -202,8 +201,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Inventory";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Inventory")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -218,8 +217,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Chat";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Chat")), rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -235,8 +233,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Toggle fly";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Toggle fly")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -250,8 +248,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
- const wchar_t *text = L"Toggle fast";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Toggle fast")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -266,7 +264,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Range select";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Range select")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -283,7 +282,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Print stacks";
- Environment->addStaticText(text, rect, false, true, this, -1);
+ Environment->addStaticText(chartowchar_t(gettext("Print stacks")),
+ rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -296,12 +296,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
- Environment->addButton(rect, this, GUI_ID_BACK_BUTTON, L"Save");
+ Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
+ chartowchar_t(gettext("Save")));
}
{
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
- Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON, L"Cancel");
+ Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
+ chartowchar_t(gettext("Cancel")));
}
}
@@ -526,67 +528,67 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
case GUI_ID_KEY_FORWARD_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->forward->setText(L"press Key");
+ this->forward->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_BACKWARD_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->backward->setText(L"press Key");
+ this->backward->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_LEFT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->left->setText(L"press Key");
+ this->left->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_RIGHT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->right->setText(L"press Key");
+ this->right->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_USE_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->use->setText(L"press Key");
+ this->use->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_FLY_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->fly->setText(L"press Key");
+ this->fly->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_FAST_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->fast->setText(L"press Key");
+ this->fast->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_JUMP_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->jump->setText(L"press Key");
+ this->jump->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_CHAT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->chat->setText(L"press Key");
+ this->chat->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_SNEAK_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->sneak->setText(L"press Key");
+ this->sneak->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_INVENTORY_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->inventory->setText(L"press Key");
+ this->inventory->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_DUMP_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->dump->setText(L"press Key");
+ this->dump->setText(chartowchar_t(gettext("press Key")));
break;
case GUI_ID_KEY_RANGE_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
- this->range->setText(L"press Key");
+ this->range->setText(chartowchar_t(gettext("press Key")));
break;
}
//Buttons
diff --git a/src/guiKeyChangeMenu.h b/src/guiKeyChangeMenu.h
index e9e359c3c..c40d802ac 100644
--- a/src/guiKeyChangeMenu.h
+++ b/src/guiKeyChangeMenu.h
@@ -26,35 +26,36 @@
#include "utility.h"
#include "modalMenu.h"
#include "client.h"
+#include "gettext.h"
#include <string>
static const char *KeyNames[] =
- { "-", "Left Button", "Right Button", "Cancel", "Middle Button", "X Button 1",
- "X Button 2", "-", "Back", "Tab", "-", "-", "Clear", "Return", "-",
- "-", "Shift", "Control", "Menu", "Pause", "Capital", "Kana", "-",
- "Junja", "Final", "Kanji", "-", "Escape", "Convert", "Nonconvert",
- "Accept", "Mode Change", "Space", "Priot", "Next", "End", "Home",
- "Left", "Up", "Right", "Down", "Select", "Print", "Execute",
- "Snapshot", "Insert", "Delete", "Help", "0", "1", "2", "3", "4", "5",
+ { "-", gettext("Left Button"), gettext("Right Button"), gettext("Cancel"), gettext("Middle Button"), gettext("X Button 1"),
+ gettext("X Button 2"), "-", gettext("Back"), gettext("Tab"), "-", "-", gettext("Clear"), gettext("Return"), "-",
+ "-", gettext("Shift"), gettext("Control"), gettext("Menu"), gettext("Pause"), gettext("Capital"), gettext("Kana"), "-",
+ gettext("Junja"), gettext("Final"), gettext("Kanji"), "-", gettext("Escape"), gettext("Convert"), gettext("Nonconvert"),
+ gettext("Accept"), gettext("Mode Change"), gettext("Space"), gettext("Priot"), gettext("Next"), gettext("End"), gettext("Home"),
+ gettext("Left"), gettext("Up"), gettext("Right"), gettext("Down"), gettext("Select"), gettext("Print"), gettext("Execute"),
+ gettext("Snapshot"), gettext("Insert"), gettext("Delete"), gettext("Help"), "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "-", "-", "-", "-", "-", "-", "-", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
- "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Left Windows",
- "Right Windows", "Apps", "-", "Sleep", "Numpad 0", "Numpad 1",
- "Numpad 2", "Numpad 3", "Numpad 4", "Numpad 5", "Numpad 6", "Numpad 7",
- "Numpad 8", "Numpad 9", "Numpad *", "Numpad +", "Numpad /", "Numpad -",
+ "R", "S", "T", "U", "V", "W", "X", "Y", "Z", gettext("Left Windows"),
+ gettext("Right Windows"), gettext("Apps"), "-", gettext("Sleep"), gettext("Numpad 0"), gettext("Numpad 1"),
+ gettext("Numpad 2"), gettext("Numpad 3"), gettext("Numpad 4"), gettext("Numpad 5"), gettext("Numpad 6"), gettext("Numpad 7"),
+ gettext("Numpad 8"), gettext("Numpad 9"), gettext("Numpad *"), gettext("Numpad +"), gettext("Numpad /"), gettext("Numpad -"),
"Numpad .", "Numpad /", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
"F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18",
"F19", "F20", "F21", "F22", "F23", "F24", "-", "-", "-", "-", "-", "-",
- "-", "-", "Num Lock", "Scroll Lock", "-", "-", "-", "-", "-", "-", "-",
- "-", "-", "-", "-", "-", "-", "-", "Left Shift", "Right Shight",
- "Left Control", "Right Control", "Left Menu", "Right Menu", "-", "-",
+ "-", "-", gettext("Num Lock"), gettext("Scroll Lock"), "-", "-", "-", "-", "-", "-", "-",
+ "-", "-", "-", "-", "-", "-", "-", gettext("Left Shift"), gettext("Right Shight"),
+ gettext("Left Control"), gettext("Right Control"), gettext("Left Menu"), gettext("Right Menu"), "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
- "-", "-", "-", "-", "-", "Plus", "Comma", "Minus", "Period", "-", "-",
+ "-", "-", "-", "-", "-", gettext("Plus"), gettext("Comma"), gettext("Minus"), gettext("Period"), "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
- "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "Attn", "CrSel",
- "ExSel", "Erase OEF", "Play", "Zoom", "PA1", "OEM Clear", "-" };
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", gettext("Attn"), gettext("CrSel"),
+ gettext("ExSel"), gettext("Erase OEF"), gettext("Play"), gettext("Zoom"), gettext("PA1"), gettext("OEM Clear"), "-" };
enum
{
GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp
index 1d7f224f6..63bc72d24 100644
--- a/src/guiMainMenu.cpp
+++ b/src/guiMainMenu.cpp
@@ -164,6 +164,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
v2s32 topleft_client(40, 0);
v2s32 size_client = size - v2s32(40, 0);
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 20, 125);
rect += topleft_client + v2s32(-15, 60);
@@ -180,6 +181,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(chartowchar_t(gettext("Name/Password")),
rect, false, true, this, -1);
}
+ changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, 50);
@@ -196,6 +198,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
e->setPasswordBox(true);
}
+ changeCtype("");
// Address + port
{
core::rect<s32> rect(0, 0, 110, 20);
@@ -203,6 +206,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(chartowchar_t(gettext("Address/Port")),
rect, false, true, this, -1);
}
+ changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, 100);
@@ -217,6 +221,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
rect += topleft_client + v2s32(size_client.X-60-100, 100);
Environment->addEditBox(text_port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
}
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 400, 20);
rect += topleft_client + v2s32(160, 100+35);
@@ -289,6 +294,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
Environment->addButton(rect, this, GUI_ID_DELETE_MAP_BUTTON,
chartowchar_t(gettext("Delete map")));
}
+ changeCtype("C");
}
void GUIMainMenu::drawMenu()
diff --git a/src/guiMessageMenu.cpp b/src/guiMessageMenu.cpp
index 155be6029..71c8fd1e8 100644
--- a/src/guiMessageMenu.cpp
+++ b/src/guiMessageMenu.cpp
@@ -85,6 +85,7 @@ void GUIMessageMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(m_message_text.c_str(), rect, false,
true, this, 256);
}
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
@@ -93,6 +94,7 @@ void GUIMessageMenu::regenerateGui(v2u32 screensize)
chartowchar_t(gettext("Proceed")));
Environment->setFocus(e);
}
+ changeCtype("C");
}
void GUIMessageMenu::drawMenu()
diff --git a/src/guiPasswordChange.cpp b/src/guiPasswordChange.cpp
index fabe75110..2a7fb009a 100644
--- a/src/guiPasswordChange.cpp
+++ b/src/guiPasswordChange.cpp
@@ -96,12 +96,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
Add stuff
*/
s32 ypos = 50;
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("Old Password")),
rect, false, true, this, -1);
}
+ changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -111,12 +113,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
e->setPasswordBox(true);
}
ypos += 50;
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("New Password")),
rect, false, true, this, -1);
}
+ changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -125,12 +129,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
e->setPasswordBox(true);
}
ypos += 50;
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("Confirm Password")),
rect, false, true, this, -1);
}
+ changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -140,6 +146,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
}
ypos += 50;
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, ypos);
@@ -156,6 +163,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
rect, false, true, this, ID_message);
e->setVisible(false);
}
+ changeCtype("C");
}
diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp
index 7745b8dd2..6cf364e5f 100644
--- a/src/guiPauseMenu.cpp
+++ b/src/guiPauseMenu.cpp
@@ -103,6 +103,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
const s32 btn_gap = 20;
const s32 btn_num = 4;
s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y);
@@ -172,7 +173,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
);*/
std::ostringstream os;
- os<<"Minetest-c55\n";
+ os<<"Minetest-delta\n";
os<<"by Perttu Ahola and contributors\n";
os<<"celeron55@gmail.com\n";
os<<BUILD_INFO<<"\n";
@@ -180,6 +181,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
}
+ changeCtype("C");
}
void GUIPauseMenu::drawMenu()
diff --git a/src/guiTextInputMenu.cpp b/src/guiTextInputMenu.cpp
index 252e452f5..a59602554 100644
--- a/src/guiTextInputMenu.cpp
+++ b/src/guiTextInputMenu.cpp
@@ -104,12 +104,14 @@ void GUITextInputMenu::regenerateGui(v2u32 screensize)
Environment->addEditBox(text.c_str(), rect, true, this, 256);
Environment->setFocus(e);
}
+ changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
Environment->addButton(rect, this, 257,
chartowchar_t(gettext("Proceed")));
}
+ changeCtype("C");
}
void GUITextInputMenu::drawMenu()
diff --git a/src/keycode.cpp b/src/keycode.cpp
index d6472d2ea..f014914d0 100644
--- a/src/keycode.cpp
+++ b/src/keycode.cpp
@@ -233,4 +233,3 @@ void clearKeyCache()
{
g_key_setting_cache.clear();
}
-
diff --git a/src/main.cpp b/src/main.cpp
index 77340cab3..6eca96eac 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1161,11 +1161,7 @@ int main(int argc, char *argv[])
// Create user data directory
fs::CreateDir(porting::path_userdata);
-#ifdef USE_GETTEXT
- setlocale(LC_MESSAGES, "");
- bindtextdomain("minetest", (porting::path_userdata+"/locale").c_str());
- textdomain("minetest");
-#endif
+ init_gettext((porting::path_data+"/../locale").c_str());
// Initialize debug streams
#ifdef RUN_IN_PLACE
@@ -1186,7 +1182,7 @@ int main(int argc, char *argv[])
BEGIN_DEBUG_EXCEPTION_HANDLER
// Print startup message
- dstream<<DTIME<<"minetest-c55"
+ dstream<<DTIME<<PROJECT_NAME
" with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
<<", "<<BUILD_INFO
<<std::endl;
diff --git a/src/map.cpp b/src/map.cpp
index 830627066..092ce97fd 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1540,6 +1540,17 @@ void Map::PrintInfo(std::ostream &out)
#define WATER_DROP_BOOST 4
+enum NeighborType {
+ NEIGHBOR_UPPER,
+ NEIGHBOR_SAME_LEVEL,
+ NEIGHBOR_LOWER
+};
+struct NodeNeighbor {
+ MapNode n;
+ NeighborType t;
+ v3s16 p;
+};
+
void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
{
DSTACK(__FUNCTION_NAME);
@@ -1559,240 +1570,220 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
v3s16 p0 = m_transforming_liquid.pop_front();
MapNode n0 = getNodeNoEx(p0);
-
- // Don't deal with non-liquids
- if(content_liquid(n0.getContent()) == false)
- continue;
-
- bool is_source = !content_flowing_liquid(n0.getContent());
-
- u8 liquid_level = 8;
- if(is_source == false)
- liquid_level = n0.param2 & 0x0f;
-
- // Turn possible source into non-source
- u8 nonsource_c = make_liquid_flowing(n0.getContent());
-
+
/*
- If not source, check that some node flows into this one
- and what is the level of liquid in this one
- */
- if(is_source == false)
- {
- s8 new_liquid_level_max = -1;
-
- v3s16 dirs_from[5] = {
- v3s16(0,1,0), // top
- v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left
- };
- for(u16 i=0; i<5; i++)
- {
- bool from_top = (i==0);
-
- v3s16 p2 = p0 + dirs_from[i];
- MapNode n2 = getNodeNoEx(p2);
-
- if(content_liquid(n2.getContent()))
- {
- u8 n2_nonsource_c = make_liquid_flowing(n2.getContent());
- // Check that the liquids are the same type
- if(n2_nonsource_c != nonsource_c)
- {
- dstream<<"WARNING: Not handling: different liquids"
- " collide"<<std::endl;
- continue;
+ Collect information about current node
+ */
+ s8 liquid_level = -1;
+ u8 liquid_kind = CONTENT_IGNORE;
+ LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
+ switch (liquid_type) {
+ case LIQUID_SOURCE:
+ liquid_level = 8;
+ liquid_kind = content_features(n0.getContent()).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)
+ continue;
+ liquid_kind = CONTENT_AIR;
+ break;
+ }
+
+ /*
+ Collect information about the environment
+ */
+ v3s16 dirs[6] = {
+ v3s16( 0, 1, 0), // top
+ v3s16( 0,-1, 0), // bottom
+ v3s16( 1, 0, 0), // right
+ v3s16(-1, 0, 0), // left
+ v3s16( 0, 0, 1), // back
+ v3s16( 0, 0,-1), // front
+ };
+ NodeNeighbor sources[6]; // surrounding sources
+ int num_sources = 0;
+ NodeNeighbor flows[6]; // surrounding flowing liquid nodes
+ int num_flows = 0;
+ NodeNeighbor airs[6]; // surrounding air
+ int num_airs = 0;
+ NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid
+ int num_neutrals = 0;
+ bool flowing_down = false;
+ for (u16 i = 0; i < 6; i++) {
+ NeighborType nt = NEIGHBOR_SAME_LEVEL;
+ switch (i) {
+ case 0:
+ nt = NEIGHBOR_UPPER;
+ break;
+ case 1:
+ nt = NEIGHBOR_LOWER;
+ break;
+ }
+ v3s16 npos = p0 + dirs[i];
+ NodeNeighbor nb = {getNodeNoEx(npos), nt, npos};
+ switch (content_features(nb.n.getContent()).liquid_type) {
+ case LIQUID_NONE:
+ if (nb.n.getContent() == CONTENT_AIR) {
+ airs[num_airs++] = nb;
+ // if the current node happens to be a flowing node, it will start to flow down here.
+ if (nb.t == NEIGHBOR_LOWER)
+ flowing_down = true;
+ } else {
+ neutrals[num_neutrals++] = nb;
}
- bool n2_is_source = !content_flowing_liquid(n2.getContent());
- s8 n2_liquid_level = 8;
- if(n2_is_source == false)
- n2_liquid_level = n2.param2 & 0x07;
-
- s8 new_liquid_level = -1;
- if(from_top)
- {
- //new_liquid_level = 7;
- if(n2_liquid_level >= 7 - WATER_DROP_BOOST)
- new_liquid_level = 7;
- else
- new_liquid_level = n2_liquid_level + WATER_DROP_BOOST;
+ break;
+ 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 = content_features(nb.n.getContent()).liquid_alternative_flowing;
+ if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
+ neutrals[num_neutrals++] = nb;
+ } else {
+ sources[num_sources++] = nb;
}
- else if(n2_liquid_level > 0)
- {
- new_liquid_level = n2_liquid_level - 1;
+ break;
+ 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 = content_features(nb.n.getContent()).liquid_alternative_flowing;
+ if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
+ neutrals[num_neutrals++] = nb;
+ } else {
+ flows[num_flows++] = nb;
+ if (nb.t == NEIGHBOR_LOWER)
+ flowing_down = true;
}
-
- if(new_liquid_level > new_liquid_level_max)
- new_liquid_level_max = new_liquid_level;
- }
- } //for
-
- /*
- If liquid level should be something else, update it and
- add all the neighboring water nodes to the transform queue.
- */
- if(new_liquid_level_max != liquid_level)
- {
- if(new_liquid_level_max == -1)
- {
- // Remove water alltoghether
- n0.setContent(CONTENT_AIR);
- n0.param2 = 0;
- setNode(p0, n0);
- }
- else
- {
- n0.param2 = new_liquid_level_max;
- setNode(p0, n0);
- }
-
- // Block has been modified
- {
- v3s16 blockpos = getNodeBlockPos(p0);
- MapBlock *block = getBlockNoCreateNoEx(blockpos);
- if(block != NULL)
- modified_blocks.insert(blockpos, block);
+ break;
+ }
+ }
+
+ /*
+ decide on the type (and possibly level) of the current node
+ */
+ u8 new_node_content;
+ s8 new_node_level = -1;
+ if (num_sources >= 2 || liquid_type == LIQUID_SOURCE) {
+ // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
+ // or the flowing alternative of the first of the surrounding sources (if it's air), so
+ // it's perfectly safe to use liquid_kind here to determine the new node content.
+ new_node_content = content_features(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;
+ new_node_level = 7;
+ } else {
+ // no surrounding sources, so get the maximum level that can flow into this node
+ for (u16 i = 0; i < num_flows; i++) {
+ u8 nb_liquid_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK);
+ switch (flows[i].t) {
+ case NEIGHBOR_UPPER:
+ if (nb_liquid_level + WATER_DROP_BOOST > new_node_level) {
+ new_node_level = 7;
+ if (nb_liquid_level + WATER_DROP_BOOST < 7)
+ new_node_level = nb_liquid_level + WATER_DROP_BOOST;
+ }
+ 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 > new_node_level) {
+ new_node_level = nb_liquid_level - 1;
+ }
+ break;
}
-
- /*
- Add neighboring non-source liquid nodes to transform queue.
- */
- v3s16 dirs[6] = {
- v3s16(0,0,1), // back
- v3s16(0,1,0), // top
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(0,-1,0), // bottom
- v3s16(-1,0,0), // left
- };
- for(u16 i=0; i<6; i++)
- {
- v3s16 p2 = p0 + dirs[i];
-
- MapNode n2 = getNodeNoEx(p2);
- if(content_flowing_liquid(n2.getContent()))
- {
- m_transforming_liquid.push_back(p2);
+ }
+ // don't flow as far in open terrain - if there isn't at least one adjacent solid block,
+ // substract another unit from the resulting water level.
+ if (!flowing_down && new_node_level >= 1) {
+ bool at_wall = false;
+ for (u16 i = 0; i < num_neutrals; i++) {
+ if (neutrals[i].t == NEIGHBOR_SAME_LEVEL) {
+ at_wall = true;
+ break;
}
}
+ if (!at_wall)
+ new_node_level -= 1;
}
+
+ if (new_node_level >= 0)
+ new_node_content = liquid_kind;
+ else
+ new_node_content = CONTENT_AIR;
}
-
- // Get a new one from queue if the node has turned into non-water
- if(content_liquid(n0.getContent()) == false)
+
+ /*
+ check if anything has changed. if not, just continue with the next node.
+ */
+ if (new_node_content == n0.getContent() && (content_features(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;
-
+
+
/*
- Flow water from this node
- */
- v3s16 dirs_to[5] = {
- v3s16(0,-1,0), // bottom
- v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left
- };
- for(u16 i=0; i<5; i++)
- {
- bool to_bottom = (i == 0);
-
- // If liquid is at lowest possible height, it's not going
- // anywhere except down
- if(liquid_level == 0 && to_bottom == false)
- continue;
-
- u8 liquid_next_level = 0;
- // If going to bottom
- if(to_bottom)
- {
- //liquid_next_level = 7;
- if(liquid_level >= 7 - WATER_DROP_BOOST)
- liquid_next_level = 7;
- else
- liquid_next_level = liquid_level + WATER_DROP_BOOST;
- }
- else
- liquid_next_level = liquid_level - 1;
-
- bool n2_changed = false;
- bool flowed = false;
-
- v3s16 p2 = p0 + dirs_to[i];
-
- MapNode n2 = getNodeNoEx(p2);
- //dstream<<"[1] n2.param="<<(int)n2.param<<std::endl;
-
- if(content_liquid(n2.getContent()))
- {
- u8 n2_nonsource_c = make_liquid_flowing(n2.getContent());
- // Check that the liquids are the same type
- if(n2_nonsource_c != nonsource_c)
- {
- dstream<<"WARNING: Not handling: different liquids"
- " collide"<<std::endl;
- continue;
- }
- bool n2_is_source = !content_flowing_liquid(n2.getContent());
- u8 n2_liquid_level = 8;
- if(n2_is_source == false)
- n2_liquid_level = n2.param2 & 0x07;
-
- if(to_bottom)
- {
- flowed = true;
- }
-
- if(n2_is_source)
- {
- // Just flow into the source, nothing changes.
- // n2_changed is not set because destination didn't change
- flowed = true;
+ update the current node
+ */
+ bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
+ n0.setContent(new_node_content);
+ if (content_features(n0.getContent()).liquid_type == LIQUID_FLOWING) {
+ // set level to last 3 bits, flowing down bit to 4th bit
+ n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
+ } else {
+ n0.param2 = 0;
+ }
+ setNode(p0, n0);
+ v3s16 blockpos = getNodeBlockPos(p0);
+ MapBlock *block = getBlockNoCreateNoEx(blockpos);
+ if(block != NULL)
+ modified_blocks.insert(blockpos, block);
+
+ /*
+ enqueue neighbors for update if neccessary
+ */
+ switch (content_features(n0.getContent()).liquid_type) {
+ case LIQUID_SOURCE:
+ // make sure source flows into all neighboring nodes
+ for (u16 i = 0; i < num_flows; i++)
+ if (flows[i].t != NEIGHBOR_UPPER)
+ m_transforming_liquid.push_back(flows[i].p);
+ for (u16 i = 0; i < num_airs; i++)
+ if (airs[i].t != NEIGHBOR_UPPER)
+ m_transforming_liquid.push_back(airs[i].p);
+ break;
+ case LIQUID_NONE:
+ // this flow has turned to air; neighboring flows might need to do the same
+ for (u16 i = 0; i < num_flows; i++)
+ m_transforming_liquid.push_back(flows[i].p);
+ break;
+ case LIQUID_FLOWING:
+ for (u16 i = 0; i < num_flows; i++) {
+ u8 flow_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK);
+ // liquid_level is still the ORIGINAL level of this node.
+ if (flows[i].t != NEIGHBOR_UPPER && ((flow_level < liquid_level || flow_level < new_node_level) ||
+ flow_down_enabled))
+ m_transforming_liquid.push_back(flows[i].p);
}
- else
- {
- if(liquid_next_level > liquid_level)
- {
- n2.param2 = liquid_next_level;
- setNode(p2, n2);
-
- n2_changed = true;
- flowed = true;
- }
+ for (u16 i = 0; i < num_airs; i++) {
+ if (airs[i].t != NEIGHBOR_UPPER && (airs[i].t == NEIGHBOR_LOWER || new_node_level > 0))
+ m_transforming_liquid.push_back(airs[i].p);
}
- }
- else if(n2.getContent() == CONTENT_AIR)
- {
- n2.setContent(nonsource_c);
- n2.param2 = liquid_next_level;
- setNode(p2, n2);
-
- n2_changed = true;
- flowed = true;
- }
-
- //dstream<<"[2] n2.param="<<(int)n2.param<<std::endl;
-
- if(n2_changed)
- {
- m_transforming_liquid.push_back(p2);
-
- v3s16 blockpos = getNodeBlockPos(p2);
- MapBlock *block = getBlockNoCreateNoEx(blockpos);
- if(block != NULL)
- modified_blocks.insert(blockpos, block);
- }
-
- // If n2_changed to bottom, don't flow anywhere else
- if(to_bottom && flowed && !is_source)
break;
}
-
+
loopcount++;
//if(loopcount >= 100000)
- if(loopcount >= initial_size * 1)
+ if(loopcount >= initial_size * 10) {
break;
+ }
}
//dstream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
}
diff --git a/src/mapnode.h b/src/mapnode.h
index aeb72c97a..1fb84e1c9 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -404,9 +404,16 @@ enum LightBank
};
/*
+ Masks for MapNode.param2 of flowing liquids
+ */
+#define LIQUID_LEVEL_MASK 0x07
+#define LIQUID_FLOW_DOWN_MASK 0x08
+
+/*
This is the stuff what the whole world consists of.
*/
+
struct MapNode
{
/*
diff --git a/src/servermain.cpp b/src/servermain.cpp
index 91fd1d3a5..dc41720fb 100644
--- a/src/servermain.cpp
+++ b/src/servermain.cpp
@@ -162,7 +162,7 @@ int main(int argc, char *argv[])
BEGIN_DEBUG_EXCEPTION_HANDLER
// Print startup message
- dstream<<DTIME<<"minetest-c55"
+ dstream<<DTIME<<PROJECT_NAME <<
" with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
<<", "<<BUILD_INFO
<<std::endl;