From a4e2198e4102f1dabc8f8720c2ace9c2fca8d999 Mon Sep 17 00:00:00 2001 From: sapier Date: Tue, 4 Mar 2014 19:57:39 +0100 Subject: [PATCH 01/53] Replace pause and message menu by formspec ones --- builtin/mainmenu.lua | 4 +- builtin/modmgr.lua | 2 +- builtin/modstore.lua | 4 +- doc/lua_api.txt | 13 +- src/CMakeLists.txt | 2 - src/game.cpp | 227 +++++++++++++++++++++----------- src/guiFormSpecMenu.cpp | 127 +++++++++++------- src/guiFormSpecMenu.h | 18 ++- src/guiMessageMenu.cpp | 173 ------------------------- src/guiMessageMenu.h | 60 --------- src/guiPauseMenu.cpp | 280 ---------------------------------------- src/guiPauseMenu.h | 63 --------- src/main.cpp | 1 - src/mainmenumanager.h | 10 +- 14 files changed, 273 insertions(+), 711 deletions(-) delete mode 100644 src/guiMessageMenu.cpp delete mode 100644 src/guiMessageMenu.h delete mode 100644 src/guiPauseMenu.cpp delete mode 100644 src/guiPauseMenu.h diff --git a/builtin/mainmenu.lua b/builtin/mainmenu.lua index f2649443..ad8b37ee 100644 --- a/builtin/mainmenu.lua +++ b/builtin/mainmenu.lua @@ -176,7 +176,7 @@ function update_menu() -- handle errors if gamedata.errormessage ~= nil then - formspec = "size[12,5.2]" .. + formspec = "size[12,5.2,true]" .. "textarea[1,2;10,2;;ERROR: " .. engine.formspec_escape(gamedata.errormessage) .. ";]".. @@ -365,7 +365,7 @@ end function tabbuilder.gettab() local tsize = tabbuilder.tabsizes[tabbuilder.current_tab] or {width=12, height=5.2} - local retval = "size[" .. tsize.width .. "," .. tsize.height .. "]" + local retval = "size[" .. tsize.width .. "," .. tsize.height .. ",true]" if tabbuilder.show_buttons then retval = retval .. tabbuilder.tab_header() diff --git a/builtin/modmgr.lua b/builtin/modmgr.lua index 11434ab3..eeb65add 100644 --- a/builtin/modmgr.lua +++ b/builtin/modmgr.lua @@ -422,7 +422,7 @@ function modmgr.dialog_configure_world() local mod = filterlist.get_list(modmgr.modlist)[modmgr.world_config_selected_mod] local retval = - "size[11,6.5]" .. + "size[11,6.5,true]" .. "label[0.5,-0.25;" .. fgettext("World:") .. "]" .. "label[1.75,-0.25;" .. worldspec.name .. "]" diff --git a/builtin/modstore.lua b/builtin/modstore.lua index 43d8d7e2..ef7fd016 100644 --- a/builtin/modstore.lua +++ b/builtin/modstore.lua @@ -98,7 +98,7 @@ end -- @function [parent=#modstore] getsuccessfuldialog function modstore.getsuccessfuldialog() local retval = "" - retval = retval .. "size[6,2]" + retval = retval .. "size[6,2,true]" if modstore.lastmodentry ~= nil then retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]" retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]" @@ -152,7 +152,7 @@ end -------------------------------------------------------------------------------- -- @function [parent=#modstore] tabheader function modstore.tabheader(tabname) - local retval = "size[12,10.25]" + local retval = "size[12,10.25,true]" retval = retval .. "tabheader[-0.3,-0.99;modstore_tab;" .. "Unsorted,Search;" .. modstore.nametoindex(tabname) .. ";true;false]" .. diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f5468494..71380075 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -849,7 +849,7 @@ Example stuff: local meta = minetest.get_meta(pos) meta:set_string("formspec", - "invsize[8,9;]".. + "size[8,9]".. "list[context;main;0,0;8,4;]".. "list[current_player;main;0,5;8,4;]") meta:set_string("infotext", "Chest"); @@ -861,7 +861,7 @@ meta:from_table({ main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "", [5] = "", [6] = "", [7] = "", [8] = "", [9] = "", [10] = "", [11] = "", [12] = "", [13] = "", [14] = "default:cobble", [15] = "", [16] = "", [17] = "", [18] = "", [19] = "", [20] = "default:cobble", [21] = "", [22] = "", [23] = "", [24] = "", [25] = "", [26] = "", [27] = "", [28] = "", [29] = "", [30] = "", [31] = "", [32] = ""} }, fields = { - formspec = "invsize[8,9;]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]", + formspec = "size[8,9]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]", infotext = "Chest" } }) @@ -876,17 +876,17 @@ examples. Examples: - Chest: - invsize[8,9;] + size[8,9] list[context;main;0,0;8,4;] list[current_player;main;0,5;8,4;] - Furnace: - invsize[8,9;] + size[8,9] list[context;fuel;2,3;1,1;] list[context;src;2,1;1,1;] list[context;dst;5,1;2,2;] list[current_player;main;0,5;8,4;] - Minecraft-like player inventory - invsize[8,7.5;] + size[8,7.5] image[1,0.6;1,2;player.png] list[current_player;main;0,3.5;8,4;] list[current_player;craft;3,0;3,3;] @@ -894,8 +894,9 @@ Examples: Elements: -size[,] +size[,,] ^ Define the size of the menu in inventory slots +^ fixed_size true/false (optional) ^ deprecated: invsize[,;] list[;;,;,;] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 562306e1..149fe4a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -424,11 +424,9 @@ set(minetest_SRCS chat.cpp hud.cpp guiKeyChangeMenu.cpp - guiMessageMenu.cpp guiTextInputMenu.cpp guiFormSpecMenu.cpp guiTable.cpp - guiPauseMenu.cpp guiPasswordChange.cpp guiVolumeChange.cpp guiDeathScreen.cpp diff --git a/src/game.cpp b/src/game.cpp index 18e69c13..64e2ffcc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "IMeshCache.h" #include "client.h" #include "server.h" -#include "guiPauseMenu.h" #include "guiPasswordChange.h" #include "guiVolumeChange.h" #include "guiFormSpecMenu.h" @@ -75,24 +74,6 @@ with this program; if not, write to the Free Software Foundation, Inc., Text input system */ -struct TextDestChat : public TextDest -{ - TextDestChat(Client *client) - { - m_client = client; - } - void gotText(std::wstring text) - { - m_client->typeChatMessage(text); - } - void gotText(std::map fields) - { - m_client->typeChatMessage(narrow_to_wide(fields["text"])); - } - - Client *m_client; -}; - struct TextDestNodeMetadata : public TextDest { TextDestNodeMetadata(v3s16 p, Client *client) @@ -136,12 +117,76 @@ struct TextDestPlayerInventory : public TextDest m_client->sendInventoryFields(m_formname, fields); } - void setFormName(std::string formname) { + Client *m_client; +}; + +struct LocalFormspecHandler : public TextDest +{ + LocalFormspecHandler(); + LocalFormspecHandler(std::string formname) { m_formname = formname; } + LocalFormspecHandler(std::string formname,Client *client) { + m_formname = formname; + m_client = client; + } + + void gotText(std::string message) { + errorstream << "LocalFormspecHandler::gotText old style message received" << std::endl; + } + + void gotText(std::map fields) + { + if (m_formname == "MT_PAUSE_MENU") { + if (fields.find("btn_sound") != fields.end()) { + g_gamecallback->changeVolume(); + return; + } + + if (fields.find("btn_exit_menu") != fields.end()) { + g_gamecallback->disconnect(); + return; + } + + if (fields.find("btn_exit_os") != fields.end()) { + g_gamecallback->exitToOS(); + return; + } + + if (fields.find("quit") != fields.end()) { + return; + } + + if (fields.find("btn_continue") != fields.end()) { + return; + } + } + if (m_formname == "MT_CHAT_MENU") { + if ((fields.find("btn_send") != fields.end()) || + (fields.find("quit") != fields.end())) { + if (fields.find("f_text") != fields.end()) { + if (m_client != 0) { + m_client->typeChatMessage(narrow_to_wide(fields["f_text"])); + } + else { + errorstream << "LocalFormspecHandler::gotText received chat message but m_client is NULL" << std::endl; + } + } + return; + } + } + + errorstream << "LocalFormspecHandler::gotText unhandled >" << m_formname << "< event" << std::endl; + int i = 0; + for (std::map::iterator iter = fields.begin(); + iter != fields.end(); iter++) { + errorstream << "\t"<< i << ": " << iter->first << "=" << iter->second << std::endl; + i++; + } + } + Client *m_client; - std::string m_formname; }; /* Respawn menu callback */ @@ -224,13 +269,9 @@ inline bool isPointableNode(const MapNode& n, Find what the player is pointing at */ PointedThing getPointedThing(Client *client, v3f player_position, - v3f camera_direction, v3f camera_position, - core::line3d shootline, f32 d, - bool liquids_pointable, - bool look_for_object, - v3s16 camera_offset, - std::vector &hilightboxes, - ClientActiveObject *&selected_object) + v3f camera_direction, v3f camera_position, core::line3d shootline, + f32 d, bool liquids_pointable, bool look_for_object, v3s16 camera_offset, + std::vector &hilightboxes, ClientActiveObject *&selected_object) { PointedThing result; @@ -379,9 +420,8 @@ PointedThing getPointedThing(Client *client, v3f player_position, Additionally, a progressbar can be drawn when percent is set between 0 and 100. */ /*gui::IGUIStaticText **/ -void draw_load_screen(const std::wstring &text, - IrrlichtDevice* device, gui::IGUIFont* font, - float dtime=0 ,int percent=0, bool clouds=true) +void draw_load_screen(const std::wstring &text, IrrlichtDevice* device, + gui::IGUIFont* font, float dtime=0 ,int percent=0, bool clouds=true) { video::IVideoDriver* driver = device->getVideoDriver(); v2u32 screensize = driver->getScreenSize(); @@ -430,8 +470,8 @@ void draw_load_screen(const std::wstring &text, /* Profiler display */ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler, - gui::IGUIFont *font, u32 text_height, - u32 show_profiler, u32 show_profiler_max) + gui::IGUIFont *font, u32 text_height, u32 show_profiler, + u32 show_profiler_max) { if(show_profiler == 0) { @@ -833,8 +873,7 @@ public: }; bool nodePlacementPrediction(Client &client, - const ItemDefinition &playeritem_def, - v3s16 nodepos, v3s16 neighbourpos) + const ItemDefinition &playeritem_def, v3s16 nodepos, v3s16 neighbourpos) { std::string prediction = playeritem_def.node_placement_prediction; INodeDefManager *nodedef = client.ndef(); @@ -930,26 +969,86 @@ bool nodePlacementPrediction(Client &client, return false; } +static void show_chat_menu(FormspecFormSource* current_formspec, + TextDest* current_textdest, IWritableTextureSource* tsrc, + IrrlichtDevice * device, Client* client, std::string text) +{ + std::string formspec = + "size[11,5.5,true]" + "field[3,2.35;6,0.5;f_text;;" + text + "]" + "button_exit[4,3;3,0.5;btn_send;" + std::string(gettext("Proceed")) + "]" + ; -void the_game( - bool &kill, - bool random_input, - InputHandler *input, - IrrlichtDevice *device, - gui::IGUIFont* font, - std::string map_dir, - std::string playername, - std::string password, - std::string address, // If "", local server is used - u16 port, - std::wstring &error_message, - ChatBackend &chat_backend, - const SubgameSpec &gamespec, // Used for local game, - bool simple_singleplayer_mode -) + /* Create menu */ + /* Note: FormspecFormSource and LocalFormspecHandler + * are deleted by guiFormSpecMenu */ + current_formspec = new FormspecFormSource(formspec,¤t_formspec); + current_textdest = new LocalFormspecHandler("MT_CHAT_MENU",client); + GUIFormSpecMenu *menu = + new GUIFormSpecMenu(device, guiroot, -1, + &g_menumgr, + NULL, NULL, tsrc); + menu->setFormSource(current_formspec); + menu->setTextDest(current_textdest); + menu->drop(); +} + +/******************************************************************************/ +static void show_pause_menu(FormspecFormSource* current_formspec, + TextDest* current_textdest, IWritableTextureSource* tsrc, + IrrlichtDevice * device) +{ + const char* control_text = gettext("Default Controls:\n" + "- WASD: move\n" + "- Space: jump/climb\n" + "- Shift: sneak/go down\n" + "- Q: drop item\n" + "- I: inventory\n" + "- Mouse: turn/look\n" + "- Mouse left: dig/punch\n" + "- Mouse right: place/use\n" + "- Mouse wheel: select item\n" + "- T: chat\n" + ); + + std::ostringstream os; + os<<"Minetest\n"; + os<setFormSource(current_formspec); + menu->setTextDest(current_textdest); + menu->drop(); +} + +/******************************************************************************/ +void the_game(bool &kill, bool random_input, InputHandler *input, + IrrlichtDevice *device, gui::IGUIFont* font, std::string map_dir, + std::string playername, std::string password, + std::string address /* If "", local server is used */, + u16 port, std::wstring &error_message, ChatBackend &chat_backend, + const SubgameSpec &gamespec /* Used for local game */, + bool simple_singleplayer_mode) { FormspecFormSource* current_formspec = 0; - TextDestPlayerInventory* current_textdest = 0; + TextDest* current_textdest = 0; video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); @@ -1788,33 +1887,15 @@ void the_game( } else if(input->wasKeyDown(EscapeKey)) { - infostream<<"the_game: " - <<"Launching pause menu"<drop(); - - // Move mouse cursor on top of the disconnect button - if(simple_singleplayer_mode) - input->setMousePos(displaycenter.X, displaycenter.Y+0); - else - input->setMousePos(displaycenter.X, displaycenter.Y+25); + show_pause_menu(current_formspec, current_textdest, tsrc, device); } else if(input->wasKeyDown(getKeySetting("keymap_chat"))) { - TextDest *dest = new TextDestChat(&client); - - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - L""))->drop(); + show_chat_menu(current_formspec, current_textdest, tsrc, device, &client,""); } else if(input->wasKeyDown(getKeySetting("keymap_cmd"))) { - TextDest *dest = new TextDestChat(&client); - - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - L"/"))->drop(); + show_chat_menu(current_formspec, current_textdest, tsrc, device, &client,"/"); } else if(input->wasKeyDown(getKeySetting("keymap_console"))) { diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 628ea354..95a090c6 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -66,12 +66,9 @@ with this program; if not, write to the Free Software Foundation, Inc., */ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, - gui::IGUIElement* parent, s32 id, - IMenuManager *menumgr, - InventoryManager *invmgr, - IGameDef *gamedef, - ISimpleTextureSource *tsrc -): + gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, + InventoryManager *invmgr, IGameDef *gamedef, + ISimpleTextureSource *tsrc) : GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr), m_device(dev), m_invmgr(invmgr), @@ -248,10 +245,11 @@ std::vector split(const std::string &s, char delim) { return tokens; } -void GUIFormSpecMenu::parseSize(parserData* data,std::string element) { +void GUIFormSpecMenu::parseSize(parserData* data,std::string element) +{ std::vector parts = split(element,','); - if (parts.size() == 2) { + if ((parts.size() == 2) || parts.size() == 3) { v2f invsize; if (parts[1].find(';') != std::string::npos) @@ -260,6 +258,13 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element) { invsize.X = stof(parts[0]); invsize.Y = stof(parts[1]); + lockSize(false); + if (parts.size() == 3) { + if (parts[2] == "true") { + lockSize(true,v2u32(800,600)); + } + } + if (m_lock) { v2u32 current_screensize = m_device->getVideoDriver()->getScreenSize(); v2u32 delta = current_screensize - m_lockscreensize; @@ -305,8 +310,8 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element) { errorstream<< "Invalid size element (" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseList(parserData* data,std::string element) { - +void GUIFormSpecMenu::parseList(parserData* data,std::string element) +{ if (m_gamedef == 0) { errorstream<<"WARNING: invalid use of 'list' with m_gamedef==0"< parts = split(element,';'); if ((parts.size() == 3) || (parts.size() == 4)) { @@ -408,7 +414,8 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) { errorstream<< "Invalid checkbox element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseImage(parserData* data,std::string element) { +void GUIFormSpecMenu::parseImage(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 3) { @@ -451,7 +458,8 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element) { errorstream<< "Invalid image element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) { +void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 3) { @@ -478,7 +486,9 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) { errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseButton(parserData* data,std::string element,std::string type) { +void GUIFormSpecMenu::parseButton(parserData* data,std::string element, + std::string type) +{ std::vector parts = split(element,';'); if (parts.size() == 4) { @@ -530,7 +540,8 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,std::stri errorstream<< "Invalid button element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) { +void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 3) || (parts.size() == 4)) { @@ -565,7 +576,8 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) { errorstream<< "Invalid background element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseTableOptions(parserData* data,std::string element) { +void GUIFormSpecMenu::parseTableOptions(parserData* data,std::string element) +{ std::vector parts = split(element,';'); data->table_options.clear(); @@ -576,7 +588,8 @@ void GUIFormSpecMenu::parseTableOptions(parserData* data,std::string element) { } } -void GUIFormSpecMenu::parseTableColumns(parserData* data,std::string element) { +void GUIFormSpecMenu::parseTableColumns(parserData* data,std::string element) +{ std::vector parts = split(element,';'); data->table_columns.clear(); @@ -595,7 +608,8 @@ void GUIFormSpecMenu::parseTableColumns(parserData* data,std::string element) { } } -void GUIFormSpecMenu::parseTable(parserData* data,std::string element) { +void GUIFormSpecMenu::parseTable(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 4) || (parts.size() == 5)) { @@ -664,7 +678,8 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element) { errorstream<< "Invalid table element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) { +void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 4) || (parts.size() == 5) || (parts.size() == 6)) { @@ -737,7 +752,8 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) { } -void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) { +void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 5) { @@ -790,7 +806,8 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) { << element << "'" << std::endl; } -void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) { +void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 4) { @@ -856,7 +873,9 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) { errorstream<< "Invalid pwdfield element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseSimpleField(parserData* data,std::vector &parts) { +void GUIFormSpecMenu::parseSimpleField(parserData* data, + std::vector &parts) +{ std::string name = parts[0]; std::string label = parts[1]; std::string default_val = parts[2]; @@ -935,7 +954,9 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,std::vector m_fields.push_back(spec); } -void GUIFormSpecMenu::parseTextArea(parserData* data,std::vector& parts,std::string type) { +void GUIFormSpecMenu::parseTextArea(parserData* data, + std::vector& parts,std::string type) +{ std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); @@ -1026,7 +1047,9 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,std::vector& p m_fields.push_back(spec); } -void GUIFormSpecMenu::parseField(parserData* data,std::string element,std::string type) { +void GUIFormSpecMenu::parseField(parserData* data,std::string element, + std::string type) +{ std::vector parts = split(element,';'); if (parts.size() == 3) { @@ -1041,7 +1064,8 @@ void GUIFormSpecMenu::parseField(parserData* data,std::string element,std::strin errorstream<< "Invalid field element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) { +void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 2) { @@ -1076,7 +1100,8 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) { errorstream<< "Invalid label element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) { +void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if (parts.size() == 2) { @@ -1116,7 +1141,9 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) { errorstream<< "Invalid vertlabel element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,std::string type) { +void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, + std::string type) +{ std::vector parts = split(element,';'); if ((parts.size() == 5) || (parts.size() == 7) || (parts.size() == 8)) { @@ -1202,7 +1229,8 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,std: errorstream<< "Invalid imagebutton element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) { +void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 4) || (parts.size() == 6)) { @@ -1269,7 +1297,8 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) { errorstream<< "Invalid TabHeader element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) { +void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) +{ if (m_gamedef == 0) { errorstream<<"WARNING: invalid use of item_image_button with m_gamedef==0"< parts = split(element,';'); if (parts.size() == 3) { @@ -1368,7 +1398,8 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) { errorstream<< "Invalid Box element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element) { +void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 1) || (parts.size() == 2)) { @@ -1383,7 +1414,8 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element) errorstream<< "Invalid bgcolor element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) { +void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) +{ std::vector parts = split(element,';'); if ((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) { @@ -1408,8 +1440,8 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) { errorstream<< "Invalid listcolors element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseElement(parserData* data,std::string element) { - +void GUIFormSpecMenu::parseElement(parserData* data,std::string element) +{ //some prechecks if (element == "") return; @@ -2132,16 +2164,22 @@ ItemStack GUIFormSpecMenu::verifySelectedItem() return ItemStack(); } -void GUIFormSpecMenu::acceptInput(bool quit=false) +void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) { if(m_text_dst) { std::map fields; - if (quit) { + if (quitmode == quit_mode_accept) { fields["quit"] = "true"; } + if (quitmode == quit_mode_cancel) { + fields["quit"] = "true"; + m_text_dst->gotText(fields); + return; + } + if (current_keys_pending.key_down) { fields["key_down"] = "true"; current_keys_pending.key_down = false; @@ -2281,10 +2319,10 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) if (event.KeyInput.PressedDown && (kp == EscapeKey || kp == getKeySetting("keymap_inventory"))) { - if (m_allowclose) { - acceptInput(true); + if (m_allowclose){ + acceptInput(quit_mode_cancel); quitMenu(); - } else { + } else { m_text_dst->gotText(narrow_to_wide("MenuQuit")); } return true; @@ -2313,7 +2351,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) break; } if (current_keys_pending.key_enter && m_allowclose) { - acceptInput(true); + acceptInput(quit_mode_accept); quitMenu(); } else { @@ -2643,7 +2681,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) if (btn_id == 257) { if (m_allowclose) { - acceptInput(true); + acceptInput(quit_mode_accept); quitMenu(); } else { acceptInput(); @@ -2666,7 +2704,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) acceptInput(); if(s.is_exit){ if (m_allowclose) { - acceptInput(true); + acceptInput(quit_mode_accept); quitMenu(); } else { m_text_dst->gotText(narrow_to_wide("ExitButton")); @@ -2685,7 +2723,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) { if (m_allowclose) { - acceptInput(true); + acceptInput(quit_mode_accept); quitMenu(); } else { @@ -2723,7 +2761,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) return Parent ? Parent->OnEvent(event) : false; } -bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color, bool quiet) +bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color, + bool quiet) { const char *hexpattern = NULL; if (value[0] == '#') { diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 1946f88e..858894e5 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -42,12 +42,22 @@ typedef enum { f_Unknown } FormspecFieldType; +typedef enum { + quit_mode_no, + quit_mode_accept, + quit_mode_cancel +} FormspecQuitMode; + struct TextDest { virtual ~TextDest() {}; // This is deprecated I guess? -celeron55 virtual void gotText(std::wstring text){} virtual void gotText(std::map fields) = 0; + virtual void setFormName(std::string formname) + { m_formname = formname;}; + + std::string m_formname; }; class IFormSource @@ -139,7 +149,8 @@ class GUIFormSpecMenu : public GUIModalMenu FieldSpec() { } - FieldSpec(const std::wstring name, const std::wstring label, const std::wstring fdeflt, int id): + FieldSpec(const std::wstring name, const std::wstring label, + const std::wstring fdeflt, int id) : fname(name), flabel(label), fdefault(fdeflt), @@ -228,7 +239,7 @@ public: void updateSelectedItem(); ItemStack verifySelectedItem(); - void acceptInput(bool quit); + void acceptInput(FormspecQuitMode quitmode); bool preprocessEvent(const SEvent& event); bool OnEvent(const SEvent& event); @@ -332,7 +343,8 @@ private: void parsePwdField(parserData* data,std::string element); void parseField(parserData* data,std::string element,std::string type); void parseSimpleField(parserData* data,std::vector &parts); - void parseTextArea(parserData* data,std::vector& parts,std::string type); + void parseTextArea(parserData* data,std::vector& parts, + std::string type); void parseLabel(parserData* data,std::string element); void parseVertLabel(parserData* data,std::string element); void parseImageButton(parserData* data,std::string element,std::string type); diff --git a/src/guiMessageMenu.cpp b/src/guiMessageMenu.cpp deleted file mode 100644 index dd9c0a26..00000000 --- a/src/guiMessageMenu.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola - -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 "guiMessageMenu.h" -#include "debug.h" -#include "serialization.h" -#include -#include -#include -#include -#include -#include - -#include "gettext.h" - -GUIMessageMenu::GUIMessageMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IMenuManager *menumgr, - std::wstring message_text -): - GUIModalMenu(env, parent, id, menumgr), - m_message_text(message_text), - m_status(false) -{ -} - -GUIMessageMenu::~GUIMessageMenu() -{ - removeChildren(); -} - -void GUIMessageMenu::removeChildren() -{ - { - gui::IGUIElement *e = getElementFromId(256); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(257); - if(e != NULL) - e->remove(); - } -} - -void GUIMessageMenu::regenerateGui(v2u32 screensize) -{ - /* - Remove stuff - */ - removeChildren(); - - /* - Calculate new sizes and positions - */ - core::rect rect( - screensize.X/2 - 580/2, - screensize.Y/2 - 300/2, - screensize.X/2 + 580/2, - screensize.Y/2 + 300/2 - ); - - DesiredRect = rect; - recalculateAbsolutePosition(false); - - v2s32 size = rect.getSize(); - - gui::IGUISkin *skin = Environment->getSkin(); - gui::IGUIFont *font = skin->getFont(); - s32 msg_h = font->getDimension(m_message_text.c_str()).Height; - s32 msg_w = font->getDimension(m_message_text.c_str()).Width; - if(msg_h > 200) - msg_h = 200; - if(msg_w > 540) - msg_w = 540; - - /* - Add stuff - */ - { - core::rect rect(0, 0, msg_w, msg_h); - rect += v2s32(size.X/2-msg_w/2, size.Y/2-30/2 - msg_h/2); - Environment->addStaticText(m_message_text.c_str(), - rect, false, true, this, -1); - } - - int bw = 140; - { - core::rect rect(0, 0, bw, 30); - rect = rect + v2s32(size.X/2-bw/2, size.Y/2-30/2+5 + msg_h/2); - wchar_t* text = wgettext("Proceed"); - gui::IGUIElement *e = - Environment->addButton(rect, this, 257, - text); - Environment->setFocus(e); - delete[] text; - } -} - -void GUIMessageMenu::drawMenu() -{ - gui::IGUISkin* skin = Environment->getSkin(); - if (!skin) - return; - video::IVideoDriver* driver = Environment->getVideoDriver(); - - video::SColor bgcolor(140,0,0,0); - driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); - - gui::IGUIElement::draw(); -} - -bool GUIMessageMenu::OnEvent(const SEvent& event) -{ - if(event.EventType==EET_KEY_INPUT_EVENT) - { - if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown) - { - m_status = true; - quitMenu(); - return true; - } - if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown) - { - m_status = true; - quitMenu(); - return true; - } - } - if(event.EventType==EET_GUI_EVENT) - { - if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST - && isVisible()) - { - if(!canTakeFocus(event.GUIEvent.Element)) - { - dstream<<"GUIMessageMenu: Not allowing focus change." - <getID()) - { - case 257: - m_status = true; - quitMenu(); - return true; - } - } - } - - return Parent ? Parent->OnEvent(event) : false; -} - diff --git a/src/guiMessageMenu.h b/src/guiMessageMenu.h deleted file mode 100644 index 8ec8e4a4..00000000 --- a/src/guiMessageMenu.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola - -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 GUIMESSAGEMENU_HEADER -#define GUIMESSAGEMENU_HEADER - -#include "irrlichttypes_extrabloated.h" -#include "modalMenu.h" -#include - -class GUIMessageMenu : public GUIModalMenu -{ -public: - GUIMessageMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IMenuManager *menumgr, - std::wstring message_text); - ~GUIMessageMenu(); - - void removeChildren(); - /* - Remove and re-add (or reposition) stuff - */ - void regenerateGui(v2u32 screensize); - - void drawMenu(); - - bool OnEvent(const SEvent& event); - - /* - true = ok'd - */ - bool getStatus() - { - return m_status; - } - -private: - std::wstring m_message_text; - bool m_status; -}; - -#endif - diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp deleted file mode 100644 index 4d5070c9..00000000 --- a/src/guiPauseMenu.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola - -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 "guiPauseMenu.h" -#include "debug.h" -#include "serialization.h" -#include "porting.h" -#include "config.h" -#include "version.h" -#include "main.h" -#include -#include -#include -#include -#include -#include "gettext.h" -#include "util/string.h" - -GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IGameCallback *gamecallback, - IMenuManager *menumgr, - bool simple_singleplayer_mode): - GUIModalMenu(env, parent, id, menumgr), - m_gamecallback(gamecallback), - m_simple_singleplayer_mode(simple_singleplayer_mode) -{ -} - -GUIPauseMenu::~GUIPauseMenu() -{ - removeChildren(); -} - -void GUIPauseMenu::removeChildren() -{ - { - gui::IGUIElement *e = getElementFromId(256); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(257); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(258); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(259); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(260); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(261); - if(e != NULL) - e->remove(); - } - { - gui::IGUIElement *e = getElementFromId(262); - if(e != NULL) - e->remove(); - } -} - -void GUIPauseMenu::regenerateGui(v2u32 screensize) -{ - /* - Remove stuff - */ - removeChildren(); - - /* - Calculate new sizes and positions - */ - core::rect rect( - screensize.X/2 - 580/2, - screensize.Y/2 - 300/2, - screensize.X/2 + 580/2, - screensize.Y/2 + 300/2 - ); - - DesiredRect = rect; - recalculateAbsolutePosition(false); - - v2s32 size = rect.getSize(); - - /* - Add stuff - */ - const s32 btn_height = 30; - const s32 btn_gap = 20; - const s32 btn_num = m_simple_singleplayer_mode ? 4 : 5; - s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2; - { - core::rect rect(0, 0, 140, btn_height); - rect = rect + v2s32(size.X/2-140/2, btn_y); - wchar_t* text = wgettext("Continue"); - Environment->addButton(rect, this, 256, - text); - delete[] text; - } - btn_y += btn_height + btn_gap; - if(!m_simple_singleplayer_mode) - { - { - core::rect rect(0, 0, 140, btn_height); - rect = rect + v2s32(size.X/2-140/2, btn_y); - wchar_t* text = wgettext("Change Password"); - Environment->addButton(rect, this, 261, - text); - delete[] text; - } - btn_y += btn_height + btn_gap; - } - { - core::rect rect(0, 0, 140, btn_height); - rect = rect + v2s32(size.X/2-140/2, btn_y); - wchar_t* text = wgettext("Sound Volume"); - Environment->addButton(rect, this, 262, - text); - delete[] text; - } - btn_y += btn_height + btn_gap; - { - core::rect rect(0, 0, 140, btn_height); - rect = rect + v2s32(size.X/2-140/2, btn_y); - wchar_t* text = wgettext("Exit to Menu"); - Environment->addButton(rect, this, 260, - text); - delete[] text; - } - btn_y += btn_height + btn_gap; - { - core::rect rect(0, 0, 140, btn_height); - rect = rect + v2s32(size.X/2-140/2, btn_y); - wchar_t* text = wgettext("Exit to OS"); - Environment->addButton(rect, this, 257, - text); - delete[] text; - } - - { - core::rect rect(0, 0, 180, 240); - rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2); - wchar_t* text = wgettext("Default Controls:\n" - "- WASD: move\n" - "- Space: jump/climb\n" - "- Shift: sneak/go down\n" - "- Q: drop item\n" - "- I: inventory\n" - "- Mouse: turn/look\n" - "- Mouse left: dig/punch\n" - "- Mouse right: place/use\n" - "- Mouse wheel: select item\n" - "- T: chat\n" - ); - Environment->addStaticText(text, rect, false, true, this, 258); - delete[] text; - - } - { - core::rect rect(0, 0, 180, 220); - rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2); - - v2u32 max_texture_size; - { - video::IVideoDriver* driver = Environment->getVideoDriver(); - max_texture_size = driver->getMaxTextureSize(); - } - - std::ostringstream os; - os<<"Minetest\n"; - os<addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259); - } -} - -void GUIPauseMenu::drawMenu() -{ - gui::IGUISkin* skin = Environment->getSkin(); - if (!skin) - return; - video::IVideoDriver* driver = Environment->getVideoDriver(); - - video::SColor bgcolor(140,0,0,0); - driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); - - gui::IGUIElement::draw(); -} - -bool GUIPauseMenu::OnEvent(const SEvent& event) -{ - - if(event.EventType==EET_KEY_INPUT_EVENT) - { - if(event.KeyInput.PressedDown) - { - if(event.KeyInput.Key==KEY_ESCAPE) - { - quitMenu(); - return true; - } - else if(event.KeyInput.Key==KEY_RETURN) - { - quitMenu(); - return true; - } - } - } - if(event.EventType==EET_GUI_EVENT) - { - if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST - && isVisible()) - { - if(!canTakeFocus(event.GUIEvent.Element)) - { - dstream<<"GUIPauseMenu: Not allowing focus change." - <getID()) - { - case 256: // continue - quitMenu(); - // ALWAYS return immediately after quitMenu() - return true; - case 261: - m_gamecallback->changePassword(); - quitMenu(); - return true; - case 262: - m_gamecallback->changeVolume(); - quitMenu(); - return true; - case 260: // disconnect - m_gamecallback->disconnect(); - quitMenu(); - return true; - case 257: // exit - m_gamecallback->exitToOS(); - quitMenu(); - return true; - } - } - } - - return Parent ? Parent->OnEvent(event) : false; -} - diff --git a/src/guiPauseMenu.h b/src/guiPauseMenu.h deleted file mode 100644 index 2808c93b..00000000 --- a/src/guiPauseMenu.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola - -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 GUIPAUSEMENU_HEADER -#define GUIPAUSEMENU_HEADER - -#include "irrlichttypes_extrabloated.h" -#include "modalMenu.h" - -class IGameCallback -{ -public: - virtual void exitToOS() = 0; - virtual void disconnect() = 0; - virtual void changePassword() = 0; - virtual void changeVolume() = 0; -}; - -class GUIPauseMenu : public GUIModalMenu -{ -public: - GUIPauseMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IGameCallback *gamecallback, - IMenuManager *menumgr, - bool simple_singleplayer_mode); - ~GUIPauseMenu(); - - void removeChildren(); - /* - Remove and re-add (or reposition) stuff - */ - void regenerateGui(v2u32 screensize); - - void drawMenu(); - - bool OnEvent(const SEvent& event); - - bool pausesGame(){ return true; } - -private: - IGameCallback *m_gamecallback; - bool m_simple_singleplayer_mode; -}; - -#endif - diff --git a/src/main.cpp b/src/main.cpp index 58312794..e5200277 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "porting.h" #include "gettime.h" -#include "guiMessageMenu.h" #include "filesys.h" #include "config.h" #include "version.h" diff --git a/src/mainmenumanager.h b/src/mainmenumanager.h index ecfb89fd..78ae1fcf 100644 --- a/src/mainmenumanager.h +++ b/src/mainmenumanager.h @@ -25,9 +25,17 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "debug.h" // assert #include "modalMenu.h" -#include "guiPauseMenu.h" //For IGameCallback #include +class IGameCallback +{ +public: + virtual void exitToOS() = 0; + virtual void disconnect() = 0; + virtual void changePassword() = 0; + virtual void changeVolume() = 0; +}; + extern gui::IGUIEnvironment* guienv; extern gui::IGUIStaticText *guiroot; From db98ef6b4553e7b7cb99589740dc219902a90fbc Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 3 Mar 2014 18:43:53 +0000 Subject: [PATCH 02/53] Stop wasting time in abm - performance improvement Unless I'm mistaken, the chunk of code I'm moving there is potentially executed hundreds of times inside the loop to get the exact same result every time --- src/environment.cpp | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 0e7830a2..9f7207b8 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -719,6 +719,29 @@ public: ServerMap *map = &m_env->getServerMap(); + // Find out how many objects the block contains + u32 active_object_count = block->m_static_objects.m_active.size(); + // Find out how many objects this and all the neighbors contain + u32 active_object_count_wider = 0; + u32 wider_unknown_count = 0; + for(s16 x=-1; x<=1; x++) + for(s16 y=-1; y<=1; y++) + for(s16 z=-1; z<=1; z++) + { + MapBlock *block2 = map->getBlockNoCreateNoEx( + block->getPos() + v3s16(x,y,z)); + if(block2==NULL){ + wider_unknown_count = 0; + continue; + } + active_object_count_wider += + block2->m_static_objects.m_active.size() + + block2->m_static_objects.m_stored.size(); + } + // Extrapolate + u32 wider_known_count = 3*3*3 - wider_unknown_count; + active_object_count_wider += wider_unknown_count * active_object_count_wider / wider_known_count; + v3s16 p0; for(p0.X=0; p0.Xm_static_objects.m_active.size(); - // Find out how many objects this and all the neighbors contain - u32 active_object_count_wider = 0; - u32 wider_unknown_count = 0; - for(s16 x=-1; x<=1; x++) - for(s16 y=-1; y<=1; y++) - for(s16 z=-1; z<=1; z++) - { - MapBlock *block2 = map->getBlockNoCreateNoEx( - block->getPos() + v3s16(x,y,z)); - if(block2==NULL){ - wider_unknown_count = 0; - continue; - } - active_object_count_wider += - block2->m_static_objects.m_active.size() - + block2->m_static_objects.m_stored.size(); - } - // Extrapolate - u32 wider_known_count = 3*3*3 - wider_unknown_count; - active_object_count_wider += wider_unknown_count * active_object_count_wider / wider_known_count; - // Call all the trigger variations i->abm->trigger(m_env, p, n); i->abm->trigger(m_env, p, n, From 28d6326bd42a88d5a9245c70d7044d19e4d07954 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 8 Mar 2014 11:34:46 -0500 Subject: [PATCH 03/53] Update set_mapgen_params and set_gen_notify Lua API to use new flag format --- src/script/common/c_content.cpp | 31 ++++++++++++++++++++----------- src/script/common/c_content.h | 9 +++++++-- src/script/lua_api/l_mapgen.cpp | 30 ++++++++++++++++-------------- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 74e1b095..899e1c53 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -840,23 +840,32 @@ void push_hit_params(lua_State *L,const HitParams ¶ms) } /******************************************************************************/ -u32 getflagsfield(lua_State *L, int table, const char *fieldname, - FlagDesc *flagdesc, u32 *flagmask) + +bool getflagsfield(lua_State *L, int table, const char *fieldname, + FlagDesc *flagdesc, u32 *flags, u32 *flagmask) { - u32 flags = 0; - lua_getfield(L, table, fieldname); - if (lua_isstring(L, -1)) { - std::string flagstr = lua_tostring(L, -1); - flags = readFlagString(flagstr, flagdesc, flagmask); - } else if (lua_istable(L, -1)) { - flags = read_flags_table(L, -1, flagdesc, flagmask); - } + bool success = read_flags(L, -1, flagdesc, flags, flagmask); lua_pop(L, 1); - return flags; + return success; +} + +bool read_flags(lua_State *L, int index, FlagDesc *flagdesc, + u32 *flags, u32 *flagmask) +{ + if (lua_isstring(L, index)) { + std::string flagstr = lua_tostring(L, index); + *flags = readFlagString(flagstr, flagdesc, flagmask); + } else if (lua_istable(L, index)) { + *flags = read_flags_table(L, index, flagdesc, flagmask); + } else { + return false; + } + + return true; } u32 read_flags_table(lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask) diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 9aed5ccf..f48c673b 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -119,9 +119,14 @@ int getenumfield (lua_State *L, const EnumString *spec, int default_); -u32 getflagsfield (lua_State *L, int table, +bool getflagsfield (lua_State *L, int table, const char *fieldname, - FlagDesc *flagdesc, u32 *flagmask); + FlagDesc *flagdesc, + u32 *flags, u32 *flagmask); + +bool read_flags (lua_State *L, int index, + FlagDesc *flagdesc, + u32 *flags, u32 *flagmask); u32 read_flags_table (lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask); diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index f357d3f4..56109a9d 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -189,9 +189,10 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L) return 0; EmergeManager *emerge = getServer(L)->getEmergeManager(); - ASSERT(emerge); + assert(emerge); std::string flagstr; + u32 flags = 0, flagmask = 0; lua_getfield(L, 1, "mgname"); if (lua_isstring(L, -1)) { @@ -216,13 +217,7 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L) "see lua_api.txt" << std::endl; } - lua_getfield(L, 1, "flags"); - if (lua_isstring(L, -1)) { - u32 flags, flagmask; - - flagstr = lua_tostring(L, -1); - flags = readFlagString(flagstr, flagdesc_mapgen, &flagmask); - + if (getflagsfield(L, 1, "flags", flagdesc_mapgen, &flags, &flagmask)) { emerge->params.flags &= ~flagmask; emerge->params.flags |= flags; } @@ -260,11 +255,13 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L) // set_gen_notify(string) int ModApiMapgen::l_set_gen_notify(lua_State *L) { - if (lua_isstring(L, 1)) { + u32 flags = 0, flagmask = 0; + + if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) { EmergeManager *emerge = getServer(L)->getEmergeManager(); - emerge->gennotify = readFlagString(lua_tostring(L, 1), - flagdesc_gennotify, NULL); + emerge->gennotify = flags; } + return 0; } @@ -407,8 +404,11 @@ int ModApiMapgen::l_register_decoration(lua_State *L) break; } case DECO_SCHEMATIC: { DecoSchematic *dschem = (DecoSchematic *)deco; - dschem->flags = getflagsfield(L, index, "flags", - flagdesc_deco_schematic, NULL); + + dschem->flags = 0; + getflagsfield(L, index, "flags", flagdesc_deco_schematic, + &dschem->flags, NULL); + dschem->rotation = (Rotation)getenumfield(L, index, "rotation", es_Rotation, ROTATE_0); @@ -482,8 +482,10 @@ int ModApiMapgen::l_register_ore(lua_State *L) ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->height_min = getintfield_default(L, index, "height_min", 0); ore->height_max = getintfield_default(L, index, "height_max", 0); - ore->flags = getflagsfield(L, index, "flags", flagdesc_ore, NULL); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.); + ore->flags = 0; + getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); + lua_getfield(L, index, "wherein"); if (lua_istable(L, -1)) { int i = lua_gettop(L); From 16a028dd6bae0c7c2e797489e12d17d719842f99 Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 9 Mar 2014 11:01:13 +0100 Subject: [PATCH 04/53] Fix race condition on exit to menu --- src/game.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 64e2ffcc..2e98d09e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1018,10 +1018,10 @@ static void show_pause_menu(FormspecFormSource* current_formspec, std::string formspec = "size[11,5.5,true]" - "button_exit[4,1;3,0.5;btn_continue;" + std::string(gettext("Continue"))+ "]" - "button[4,2;3,0.5;btn_sound;" + std::string(gettext("Sound Volume")) + "]" - "button[4,3;3,0.5;btn_exit_menu;" + std::string(gettext("Exit to Menu")) + "]" - "button[4,4;3,0.5;btn_exit_os;" + std::string(gettext("Exit to OS")) + "]" + "button_exit[4,1;3,0.5;btn_continue;" + std::string(gettext("Continue")) + "]" + "button_exit[4,2;3,0.5;btn_sound;" + std::string(gettext("Sound Volume")) + "]" + "button_exit[4,3;3,0.5;btn_exit_menu;" + std::string(gettext("Exit to Menu")) + "]" + "button_exit[4,4;3,0.5;btn_exit_os;" + std::string(gettext("Exit to OS")) + "]" "textarea[7.5,0.25;3.75,6;;" + std::string(control_text) + ";]" "textarea[0.4,0.25;3.5,6;;" + os.str() + ";]" ; From 0643cef09a741d1e8a7b971f3ae70b45ac8d44bf Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Thu, 6 Mar 2014 19:20:06 +0000 Subject: [PATCH 05/53] Update ABM object counts when triggers add objects Also fixes long-standing accuracy issue due to unknown wider object count not being incremented. --- src/environment.cpp | 49 ++++++++++++++++++++++++++++++--------------- src/environment.h | 4 ++++ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 9f7207b8..3593c94f 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -712,17 +712,13 @@ public: } } } - void apply(MapBlock *block) + // Find out how many objects the given block and its neighbours contain. + // Returns the number of objects in the block, and also in 'wider' the + // number of objects in the block and all its neighbours. The latter + // may an estimate if any neighbours are unloaded. + u32 countObjects(MapBlock *block, ServerMap * map, u32 &wider) { - if(m_aabms.empty()) - return; - - ServerMap *map = &m_env->getServerMap(); - - // Find out how many objects the block contains - u32 active_object_count = block->m_static_objects.m_active.size(); - // Find out how many objects this and all the neighbors contain - u32 active_object_count_wider = 0; + wider = 0; u32 wider_unknown_count = 0; for(s16 x=-1; x<=1; x++) for(s16 y=-1; y<=1; y++) @@ -731,17 +727,30 @@ public: MapBlock *block2 = map->getBlockNoCreateNoEx( block->getPos() + v3s16(x,y,z)); if(block2==NULL){ - wider_unknown_count = 0; + wider_unknown_count++; continue; } - active_object_count_wider += - block2->m_static_objects.m_active.size() + wider += block2->m_static_objects.m_active.size() + block2->m_static_objects.m_stored.size(); } // Extrapolate + u32 active_object_count = block->m_static_objects.m_active.size(); u32 wider_known_count = 3*3*3 - wider_unknown_count; - active_object_count_wider += wider_unknown_count * active_object_count_wider / wider_known_count; - + wider += wider_unknown_count * wider / wider_known_count; + return active_object_count; + + } + void apply(MapBlock *block) + { + if(m_aabms.empty()) + return; + + ServerMap *map = &m_env->getServerMap(); + + u32 active_object_count_wider; + u32 active_object_count = this->countObjects(block, map, active_object_count_wider); + m_env->m_added_objects = 0; + v3s16 p0; for(p0.X=0; p0.Xabm->trigger(m_env, p, n); i->abm->trigger(m_env, p, n, - active_object_count, active_object_count_wider); + active_object_count, + active_object_count_wider + active_object_count); + + // Count surrounding objects again if the abms added any + if(m_env->m_added_objects > 0) { + active_object_count = countObjects(block, map, active_object_count_wider); + m_env->m_added_objects = 0; + } } } } @@ -1358,6 +1374,7 @@ u16 getFreeServerActiveObjectId( u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) { assert(object); + m_added_objects++; u16 id = addActiveObjectRaw(object, true, 0); return id; } diff --git a/src/environment.h b/src/environment.h index 8cc0bcd7..d99e27ba 100644 --- a/src/environment.h +++ b/src/environment.h @@ -105,6 +105,9 @@ public: m_day_night_ratio_override = value; } + // counter used internally when triggering ABMs + u32 m_added_objects; + protected: // peer_ids in here should be unique, except that there may be many 0s std::list m_players; @@ -118,6 +121,7 @@ protected: // Overriding the day-night ratio is useful for custom sky visuals bool m_enable_day_night_ratio_override; u32 m_day_night_ratio_override; + }; /* From 5ce3f8f7b773e915e82f7a4616743dd820f51df4 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Fri, 7 Mar 2014 21:06:43 +0000 Subject: [PATCH 06/53] Correct misleading detached inventory error message Looks like a bit of hasty copying and pasting from s_item.cpp. --- src/script/cpp_api/s_inventory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index 8542f029..db3c13fe 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -232,7 +232,7 @@ bool ScriptApiDetached::getDetachedInventoryCallback( // Should be a table if(lua_type(L, -1) != LUA_TTABLE) { - errorstream<<"Item \""< Date: Tue, 11 Mar 2014 17:48:34 +0100 Subject: [PATCH 07/53] Fix generating winresource.o with build dir != source dir --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 149fe4a4..24bbe7e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -393,7 +393,7 @@ if(WIN32) set(CMAKE_RC_COMPILER "windres.exe") endif() ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o - COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_BINARY_DIR} -i${WINRESOURCE_FILE} -o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} From c9b64206f9cc4f9332cc903816799fcafb4fb7c9 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 11 Mar 2014 12:59:02 -0400 Subject: [PATCH 08/53] Fix error when calling minetest.node_punch without a pointed_thing --- builtin/item.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/item.lua b/builtin/item.lua index de546c2e..002c14f5 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -367,7 +367,7 @@ function minetest.node_punch(pos, node, puncher, pointed_thing) -- Copy pos and node because callback can modify them local pos_copy = vector.new(pos) local node_copy = {name=node.name, param1=node.param1, param2=node.param2} - local pointed_thing_copy = copy_pointed_thing(pointed_thing) + local pointed_thing_copy = pointed_thing and copy_pointed_thing(pointed_thing) or nil callback(pos_copy, node_copy, puncher, pointed_thing_copy) end end From 2bc2ce3bd159cc7aa7054059ad413e93d05d0211 Mon Sep 17 00:00:00 2001 From: Selat Date: Wed, 5 Mar 2014 18:14:40 +0300 Subject: [PATCH 09/53] Remove goto from Environment::removePlayer --- src/environment.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 3593c94f..4b842577 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -85,19 +85,17 @@ void Environment::addPlayer(Player *player) void Environment::removePlayer(u16 peer_id) { DSTACK(__FUNCTION_NAME); -re_search: + for(std::list::iterator i = m_players.begin(); - i != m_players.end(); ++i) + i != m_players.end();) { Player *player = *i; - if(player->peer_id != peer_id) - continue; - - delete player; - m_players.erase(i); - // See if there is an another one - // (shouldn't be, but just to be sure) - goto re_search; + if(player->peer_id == peer_id) { + delete player; + i = m_players.erase(i); + } else { + ++i; + } } } From 7cac34c807b6f38eaca3bc8296566493c8874e03 Mon Sep 17 00:00:00 2001 From: Selat Date: Thu, 27 Feb 2014 23:12:59 +0300 Subject: [PATCH 10/53] Pass arguments by reference --- src/client.cpp | 4 ++-- src/client.h | 4 ++-- src/connection.cpp | 4 ++-- src/content_sao.cpp | 4 ++-- src/content_sao.h | 4 ++-- src/convert_json.cpp | 4 ++-- src/convert_json.h | 4 ++-- src/exceptions.h | 34 +++++++++++++++++----------------- src/guiFormSpecMenu.h | 4 ++-- src/mods.h | 2 +- src/script/cpp_api/s_base.cpp | 2 +- src/server.cpp | 16 ++++++++-------- src/server.h | 10 +++++----- src/sound_openal.cpp | 2 +- 14 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 4d6c0cb9..654052ac 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2072,8 +2072,8 @@ void Client::sendChatMessage(const std::wstring &message) Send(0, data, true); } -void Client::sendChangePassword(const std::wstring oldpassword, - const std::wstring newpassword) +void Client::sendChangePassword(const std::wstring &oldpassword, + const std::wstring &newpassword) { Player *player = m_env.getLocalPlayer(); if(player == NULL) diff --git a/src/client.h b/src/client.h index 01cd3a01..f2e1b86d 100644 --- a/src/client.h +++ b/src/client.h @@ -349,8 +349,8 @@ public: const std::map &fields); void sendInventoryAction(InventoryAction *a); void sendChatMessage(const std::wstring &message); - void sendChangePassword(const std::wstring oldpassword, - const std::wstring newpassword); + void sendChangePassword(const std::wstring &oldpassword, + const std::wstring &newpassword); void sendDamage(u8 damage); void sendBreath(u16 breath); void sendRespawn(); diff --git a/src/connection.cpp b/src/connection.cpp index f8c68ed2..8a23f67c 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1170,7 +1170,7 @@ void UDPPeer::RunCommandQueues( channels[i].queued_commands.push_front(c); } } - catch (ItemNotFoundException e) { + catch (ItemNotFoundException &e) { // intentionally empty } } @@ -2067,7 +2067,7 @@ void ConnectionReceiveThread::receive() m_connection->putEvent(e); } } - catch(ProcessedSilentlyException e) { + catch(ProcessedSilentlyException &e) { /* try reading again */ } } diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 52b74136..095c6b5b 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -191,7 +191,7 @@ public: } ItemSAO(ServerEnvironment *env, v3f pos, - const std::string itemstring): + const std::string &itemstring): ServerActiveObject(env, pos), m_itemstring(itemstring), m_itemstring_changed(false), @@ -350,7 +350,7 @@ private: ItemSAO proto_ItemSAO(NULL, v3f(0,0,0), ""); ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos, - const std::string itemstring) + const std::string &itemstring) { return new ItemSAO(env, pos, itemstring); } diff --git a/src/content_sao.h b/src/content_sao.h index 1be620f2..63e8ef46 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "object_properties.h" ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos, - const std::string itemstring); + const std::string &itemstring); /* LuaEntitySAO needs some internals exposed. @@ -37,7 +37,7 @@ class LuaEntitySAO : public ServerActiveObject { public: LuaEntitySAO(ServerEnvironment *env, v3f pos, - const std::string &name, const std::string &state); + const std::string &name, const std::string &state); ~LuaEntitySAO(); u8 getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; } diff --git a/src/convert_json.cpp b/src/convert_json.cpp index c8e57aaf..6f227e79 100644 --- a/src/convert_json.cpp +++ b/src/convert_json.cpp @@ -31,8 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "httpfetch.h" #include "porting.h" -Json::Value fetchJsonValue(const std::string url, - struct curl_slist *chunk) { +Json::Value fetchJsonValue(const std::string &url, + struct curl_slist *chunk) { #if USE_CURL HTTPFetchRequest fetchrequest; diff --git a/src/convert_json.h b/src/convert_json.h index 3fa9903b..ea9bafb7 100644 --- a/src/convert_json.h +++ b/src/convert_json.h @@ -28,7 +28,7 @@ struct ModStoreModDetails; std::vector readModStoreList(Json::Value& modlist); ModStoreModDetails readModStoreModDetails(Json::Value& details); -Json::Value fetchJsonValue(const std::string url, - struct curl_slist *chunk); +Json::Value fetchJsonValue(const std::string &url, + struct curl_slist *chunk); #endif diff --git a/src/exceptions.h b/src/exceptions.h index 6fb97f3e..970c68e4 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class BaseException : public std::exception { public: - BaseException(const std::string s) throw() + BaseException(const std::string &s) throw() { m_s = s; } @@ -42,78 +42,78 @@ protected: class AsyncQueuedException : public BaseException { public: - AsyncQueuedException(std::string s): BaseException(s) {} + AsyncQueuedException(const std::string &s): BaseException(s) {} }; class NotImplementedException : public BaseException { public: - NotImplementedException(std::string s): BaseException(s) {} + NotImplementedException(const std::string &s): BaseException(s) {} }; class AlreadyExistsException : public BaseException { public: - AlreadyExistsException(std::string s): BaseException(s) {} + AlreadyExistsException(const std::string &s): BaseException(s) {} }; class VersionMismatchException : public BaseException { public: - VersionMismatchException(std::string s): BaseException(s) {} + VersionMismatchException(const std::string &s): BaseException(s) {} }; class FileNotGoodException : public BaseException { public: - FileNotGoodException(std::string s): BaseException(s) {} + FileNotGoodException(const std::string &s): BaseException(s) {} }; class SerializationError : public BaseException { public: - SerializationError(std::string s): BaseException(s) {} + SerializationError(const std::string &s): BaseException(s) {} }; class LoadError : public BaseException { public: - LoadError(std::string s): BaseException(s) {} + LoadError(const std::string &s): BaseException(s) {} }; class ContainerFullException : public BaseException { public: - ContainerFullException(std::string s): BaseException(s) {} + ContainerFullException(const std::string &s): BaseException(s) {} }; class SettingNotFoundException : public BaseException { public: - SettingNotFoundException(std::string s): BaseException(s) {} + SettingNotFoundException(const std::string &s): BaseException(s) {} }; class InvalidFilenameException : public BaseException { public: - InvalidFilenameException(std::string s): BaseException(s) {} + InvalidFilenameException(const std::string &s): BaseException(s) {} }; class ProcessingLimitException : public BaseException { public: - ProcessingLimitException(std::string s): BaseException(s) {} + ProcessingLimitException(const std::string &s): BaseException(s) {} }; class CommandLineError : public BaseException { public: - CommandLineError(std::string s): BaseException(s) {} + CommandLineError(const std::string &s): BaseException(s) {} }; class ItemNotFoundException : public BaseException { public: - ItemNotFoundException(std::string s): BaseException(s) {} + ItemNotFoundException(const std::string &s): BaseException(s) {} }; class ServerError : public BaseException { public: - ServerError(std::string s): BaseException(s) {} + ServerError(const std::string &s): BaseException(s) {} }; // Only used on Windows (SEH) class FatalSystemException : public BaseException { public: - FatalSystemException(std::string s): BaseException(s) {} + FatalSystemException(const std::string &s): BaseException(s) {} }; /* @@ -126,7 +126,7 @@ public: InvalidPositionException(): BaseException("Somebody tried to get/set something in a nonexistent position.") {} - InvalidPositionException(std::string s): + InvalidPositionException(const std::string &s): BaseException(s) {} }; diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 858894e5..3fc1b574 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -149,8 +149,8 @@ class GUIFormSpecMenu : public GUIModalMenu FieldSpec() { } - FieldSpec(const std::wstring name, const std::wstring label, - const std::wstring fdeflt, int id) : + FieldSpec(const std::wstring &name, const std::wstring &label, + const std::wstring &fdeflt, int id) : fname(name), flabel(label), fdefault(fdeflt), diff --git a/src/mods.h b/src/mods.h index dedcc989..f11401a1 100644 --- a/src/mods.h +++ b/src/mods.h @@ -66,7 +66,7 @@ struct ModSpec bool is_modpack; // if modpack: std::map modpack_content; - ModSpec(const std::string name_="", const std::string path_=""): + ModSpec(const std::string &name_="", const std::string &path_=""): name(name_), path(path_), depends(), diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 89827174..e28a34ee 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -43,7 +43,7 @@ class ModNameStorer private: lua_State *L; public: - ModNameStorer(lua_State *L_, const std::string modname): + ModNameStorer(lua_State *L_, const std::string &modname): L(L_) { // Store current modname in registry diff --git a/src/server.cpp b/src/server.cpp index 7eb78f3e..ba7ac1ec 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3046,8 +3046,8 @@ void Server::SendChatMessage(u16 peer_id, const std::wstring &message) } } -void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, - const std::string formname) +void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, + const std::string &formname) { DSTACK(__FUNCTION_NAME); @@ -3871,8 +3871,8 @@ struct SendableMediaAnnouncement std::string name; std::string sha1_digest; - SendableMediaAnnouncement(const std::string name_="", - const std::string sha1_digest_=""): + SendableMediaAnnouncement(const std::string &name_="", + const std::string &sha1_digest_=""): name(name_), sha1_digest(sha1_digest_) {} @@ -3933,8 +3933,8 @@ struct SendableMedia std::string path; std::string data; - SendableMedia(const std::string &name_="", const std::string path_="", - const std::string &data_=""): + SendableMedia(const std::string &name_="", const std::string &path_="", + const std::string &data_=""): name(name_), path(path_), data(data_) @@ -4385,7 +4385,7 @@ std::string Server::getBanDescription(const std::string &ip_or_name) return m_banmanager->getBanDescription(ip_or_name); } -void Server::notifyPlayer(const char *name, const std::wstring msg) +void Server::notifyPlayer(const char *name, const std::wstring &msg) { Player *player = m_env->getPlayer(name); if(!player) @@ -4498,7 +4498,7 @@ bool Server::overrideDayNightRatio(Player *player, bool do_override, return true; } -void Server::notifyPlayers(const std::wstring msg) +void Server::notifyPlayers(const std::wstring &msg) { SendChatMessage(PEER_ID_INEXISTENT,msg); } diff --git a/src/server.h b/src/server.h index 7ad9bcaf..7813eabb 100644 --- a/src/server.h +++ b/src/server.h @@ -122,8 +122,8 @@ struct MediaInfo std::string path; std::string sha1_digest; - MediaInfo(const std::string path_="", - const std::string sha1_digest_=""): + MediaInfo(const std::string &path_="", + const std::string &sha1_digest_=""): path(path_), sha1_digest(sha1_digest_) { @@ -229,8 +229,8 @@ public: void unsetIpBanned(const std::string &ip_or_name); std::string getBanDescription(const std::string &ip_or_name); - void notifyPlayer(const char *name, const std::wstring msg); - void notifyPlayers(const std::wstring msg); + void notifyPlayer(const char *name, const std::wstring &msg); + void notifyPlayers(const std::wstring &msg); void spawnParticle(const char *playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, @@ -357,7 +357,7 @@ private: void SendMovePlayer(u16 peer_id); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); - void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname); + void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname); void SendHUDAdd(u16 peer_id, u32 id, HudElement *form); void SendHUDRemove(u16 peer_id, u32 id); void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value); diff --git a/src/sound_openal.cpp b/src/sound_openal.cpp index 0cfbc279..d27526b5 100644 --- a/src/sound_openal.cpp +++ b/src/sound_openal.cpp @@ -391,7 +391,7 @@ public: } /* If buffer does not exist, consult the fetcher */ - SoundBuffer* getFetchBuffer(const std::string name) + SoundBuffer* getFetchBuffer(const std::string &name) { SoundBuffer *buf = getBuffer(name); if(buf) From 18577f25277f269c8dd8d2bdcaaccbac72d9370d Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Wed, 12 Mar 2014 19:37:19 -0400 Subject: [PATCH 11/53] Replace usage of long long with u64/s64 --- src/database-dummy.cpp | 2 +- src/database-dummy.h | 5 +++-- src/database.cpp | 10 +++++----- src/database.h | 5 +++-- src/game.cpp | 2 +- src/util/serialize.cpp | 3 ++- src/util/string.h | 2 +- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/database-dummy.cpp b/src/database-dummy.cpp index acc19ca0..c4794d28 100644 --- a/src/database-dummy.cpp +++ b/src/database-dummy.cpp @@ -151,7 +151,7 @@ MapBlock* Database_Dummy::loadBlock(v3s16 blockpos) void Database_Dummy::listAllLoadableBlocks(std::list &dst) { - for(std::map::iterator x = m_database.begin(); x != m_database.end(); ++x) + for(std::map::iterator x = m_database.begin(); x != m_database.end(); ++x) { v3s16 p = getIntegerAsBlock(x->first); //dstream<<"block_i="< #include +#include "database.h" +#include "irrlichttypes.h" class ServerMap; @@ -39,6 +40,6 @@ public: ~Database_Dummy(); private: ServerMap *srvmap; - std::map m_database; + std::map m_database; }; #endif diff --git a/src/database.cpp b/src/database.cpp index b793cd2f..e3d92f91 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -36,13 +36,13 @@ static s64 pythonmodulo(s64 i, s64 mod) return mod - ((-i) % mod); } -long long Database::getBlockAsInteger(const v3s16 pos) { - return (unsigned long long)pos.Z*16777216 + - (unsigned long long)pos.Y*4096 + - (unsigned long long)pos.X; +s64 Database::getBlockAsInteger(const v3s16 pos) { + return (u64) pos.Z * 16777216 + + (u64) pos.Y * 4096 + + (u64) pos.X; } -v3s16 Database::getIntegerAsBlock(long long i) { +v3s16 Database::getIntegerAsBlock(s64 i) { s32 x = unsignedToSigned(pythonmodulo(i, 4096), 2048); i = (i - x) / 4096; s32 y = unsignedToSigned(pythonmodulo(i, 4096), 2048); diff --git a/src/database.h b/src/database.h index 79cabe6a..4ce80ed9 100644 --- a/src/database.h +++ b/src/database.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irr_v3d.h" +#include "irrlichttypes.h" class MapBlock; @@ -33,8 +34,8 @@ public: virtual void saveBlock(MapBlock *block)=0; virtual MapBlock* loadBlock(v3s16 blockpos)=0; - long long getBlockAsInteger(const v3s16 pos); - v3s16 getIntegerAsBlock(long long i); + s64 getBlockAsInteger(const v3s16 pos); + v3s16 getIntegerAsBlock(s64 i); virtual void listAllLoadableBlocks(std::list &dst)=0; virtual int Initialized(void)=0; virtual ~Database() {}; diff --git a/src/game.cpp b/src/game.cpp index 2e98d09e..d4d6d5c0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3214,7 +3214,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, <<") (yaw="<<(wrapDegrees_0_360(camera_yaw)) <<") (t="<setText(narrow_to_wide(os.str()).c_str()); guitext2->setVisible(true); diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index 12638500..58f569fb 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "util/string.h" #include "../exceptions.h" +#include "../irrlichttypes.h" #include #include @@ -428,7 +429,7 @@ bool serializeStructToString(std::string *outstr, bufpos += PADDING(bufpos, u64); nprinted = snprintf(sbuf + pos, sbuflen, is_unsigned ? "%llu, " : "%lli, ", - (unsigned long long)*((u64 *)bufpos)); + *((u64 *)bufpos)); bufpos += sizeof(u64); } break; diff --git a/src/util/string.h b/src/util/string.h index 9bb89f14..bed66417 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -165,7 +165,7 @@ inline s32 mystoi(const std::string &s, s32 min, s32 max) inline s64 stoi64(const std::string &s) { std::stringstream tmp(s); - long long t; + s64 t; tmp >> t; return t; } From 03297acbf4efba9a19a7f31950cb6f2bc3c65ec8 Mon Sep 17 00:00:00 2001 From: BlockMen Date: Thu, 13 Mar 2014 14:00:10 +0100 Subject: [PATCH 12/53] Fix special characters in pause and message menu --- src/game.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index d4d6d5c0..a3c16245 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -976,7 +976,7 @@ static void show_chat_menu(FormspecFormSource* current_formspec, std::string formspec = "size[11,5.5,true]" "field[3,2.35;6,0.5;f_text;;" + text + "]" - "button_exit[4,3;3,0.5;btn_send;" + std::string(gettext("Proceed")) + "]" + "button_exit[4,3;3,0.5;btn_send;" + wide_to_narrow(wstrgettext("Proceed")) + "]" ; /* Create menu */ @@ -998,7 +998,8 @@ static void show_pause_menu(FormspecFormSource* current_formspec, TextDest* current_textdest, IWritableTextureSource* tsrc, IrrlichtDevice * device) { - const char* control_text = gettext("Default Controls:\n" + + std::string control_text = wide_to_narrow(wstrgettext("Default Controls:\n" "- WASD: move\n" "- Space: jump/climb\n" "- Shift: sneak/go down\n" @@ -1009,7 +1010,7 @@ static void show_pause_menu(FormspecFormSource* current_formspec, "- Mouse right: place/use\n" "- Mouse wheel: select item\n" "- T: chat\n" - ); + )); std::ostringstream os; os<<"Minetest\n"; @@ -1018,11 +1019,11 @@ static void show_pause_menu(FormspecFormSource* current_formspec, std::string formspec = "size[11,5.5,true]" - "button_exit[4,1;3,0.5;btn_continue;" + std::string(gettext("Continue")) + "]" - "button_exit[4,2;3,0.5;btn_sound;" + std::string(gettext("Sound Volume")) + "]" - "button_exit[4,3;3,0.5;btn_exit_menu;" + std::string(gettext("Exit to Menu")) + "]" - "button_exit[4,4;3,0.5;btn_exit_os;" + std::string(gettext("Exit to OS")) + "]" - "textarea[7.5,0.25;3.75,6;;" + std::string(control_text) + ";]" + "button_exit[4,1;3,0.5;btn_continue;" + wide_to_narrow(wstrgettext("Continue")) + "]" + "button_exit[4,2;3,0.5;btn_sound;" + wide_to_narrow(wstrgettext("Sound Volume")) + "]" + "button_exit[4,3;3,0.5;btn_exit_menu;" + wide_to_narrow(wstrgettext("Exit to Menu")) + "]" + "button_exit[4,4;3,0.5;btn_exit_os;" + wide_to_narrow(wstrgettext("Exit to OS")) + "]" + "textarea[7.5,0.25;3.75,6;;" + control_text + ";]" "textarea[0.4,0.25;3.5,6;;" + os.str() + ";]" ; From e4d1970abfd6206aa8780cb6cafd2efc46a2666f Mon Sep 17 00:00:00 2001 From: BlockMen Date: Thu, 13 Mar 2014 14:06:18 +0100 Subject: [PATCH 13/53] Fix game pause in singleplayer --- src/game.cpp | 5 +++++ src/guiFormSpecMenu.cpp | 1 + src/guiFormSpecMenu.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/game.cpp b/src/game.cpp index a3c16245..2b14b2c8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -988,6 +988,7 @@ static void show_chat_menu(FormspecFormSource* current_formspec, new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr, NULL, NULL, tsrc); + menu->doPause = false; menu->setFormSource(current_formspec); menu->setTextDest(current_textdest); menu->drop(); @@ -1034,6 +1035,7 @@ static void show_pause_menu(FormspecFormSource* current_formspec, current_textdest = new LocalFormspecHandler("MT_PAUSE_MENU"); GUIFormSpecMenu *menu = new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr, NULL, NULL, tsrc); + menu->doPause = true; menu->setFormSource(current_formspec); menu->setTextDest(current_textdest); menu->drop(); @@ -1881,6 +1883,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, PlayerInventoryFormSource *src = new PlayerInventoryFormSource(&client); assert(src); + menu->doPause = false; menu->setFormSpec(src->getForm(), inventoryloc); menu->setFormSource(src); menu->setTextDest(new TextDestPlayerInventory(&client)); @@ -2399,6 +2402,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr, &client, gamedef, tsrc); + menu->doPause = false; menu->setFormSource(current_formspec); menu->setTextDest(current_textdest); menu->drop(); @@ -2953,6 +2957,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr, &client, gamedef, tsrc); + menu->doPause = false; menu->setFormSpec(meta->getString("formspec"), inventoryloc); menu->setFormSource(new NodeMetadataFormSource( diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 95a090c6..4751978d 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -2320,6 +2320,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) kp == getKeySetting("keymap_inventory"))) { if (m_allowclose){ + doPause = false; acceptInput(quit_mode_cancel); quitMenu(); } else { diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 3fc1b574..6f7de158 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -242,6 +242,8 @@ public: void acceptInput(FormspecQuitMode quitmode); bool preprocessEvent(const SEvent& event); bool OnEvent(const SEvent& event); + bool doPause; + bool pausesGame() { return doPause; } GUITable* getTable(std::wstring tablename); From 875f1327a47f78d783c3abc7f7acc3977dc286ec Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Thu, 13 Mar 2014 11:07:52 -0400 Subject: [PATCH 14/53] Use fixed-width format specifiers in serializeStructToString --- src/util/serialize.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index 58f569fb..170daa0f 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "../exceptions.h" #include "../irrlichttypes.h" +#include // For PRIxN, cinttypes is C++11-only #include #include #include @@ -416,19 +417,19 @@ bool serializeStructToString(std::string *outstr, if (width == 16) { bufpos += PADDING(bufpos, u16); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%u, " : "%d, ", + is_unsigned ? "%" PRIu16 ", " : "%" PRIi16 ", ", *((u16 *)bufpos)); bufpos += sizeof(u16); } else if (width == 32) { bufpos += PADDING(bufpos, u32); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%u, " : "%d, ", + is_unsigned ? "%" PRIu32 ", " : "%" PRIi32 ", ", *((u32 *)bufpos)); bufpos += sizeof(u32); } else if (width == 64) { bufpos += PADDING(bufpos, u64); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%llu, " : "%lli, ", + is_unsigned ? "%" PRIu64 ", " : "%" PRIi64 ", ", *((u64 *)bufpos)); bufpos += sizeof(u64); } From d753d352f15ac3586a80b42dd4da6aca518c8ec8 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Fri, 14 Mar 2014 11:20:52 -0400 Subject: [PATCH 15/53] Revert "Use fixed-width format specifiers in serializeStructToString" This reverts commit 875f1327a47f78d783c3abc7f7acc3977dc286ec. Fixed width format specifiers are only officially availale in C99 and C++11. --- src/util/serialize.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index 170daa0f..069ec538 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "../exceptions.h" #include "../irrlichttypes.h" -#include // For PRIxN, cinttypes is C++11-only #include #include #include @@ -417,20 +416,20 @@ bool serializeStructToString(std::string *outstr, if (width == 16) { bufpos += PADDING(bufpos, u16); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%" PRIu16 ", " : "%" PRIi16 ", ", + is_unsigned ? "%u, " : "%d, ", *((u16 *)bufpos)); bufpos += sizeof(u16); } else if (width == 32) { bufpos += PADDING(bufpos, u32); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%" PRIu32 ", " : "%" PRIi32 ", ", + is_unsigned ? "%u, " : "%d, ", *((u32 *)bufpos)); bufpos += sizeof(u32); } else if (width == 64) { bufpos += PADDING(bufpos, u64); nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%" PRIu64 ", " : "%" PRIi64 ", ", - *((u64 *)bufpos)); + is_unsigned ? "%llu, " : "%lli, ", + (unsigned long long)*((u64 *)bufpos)); bufpos += sizeof(u64); } break; From 362ef5f6ced862daa4733034810d0b07e2ad5d89 Mon Sep 17 00:00:00 2001 From: Sfan5 Date: Sat, 15 Mar 2014 14:49:30 +0100 Subject: [PATCH 16/53] Make sure we get a stacktrace for as many lua errors as possible --- src/script/common/c_content.cpp | 4 ++-- src/script/common/c_internal.cpp | 2 +- src/script/cpp_api/s_inventory.cpp | 6 +++--- src/script/cpp_api/s_nodemeta.cpp | 6 +++--- src/script/cpp_api/s_server.cpp | 12 ++++++------ src/script/lua_api/l_craft.cpp | 28 ++++++++++++++-------------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 899e1c53..4730ca14 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -654,7 +654,7 @@ ItemStack read_item(lua_State* L, int index,Server* srv) } else { - throw LuaError(NULL, "Expecting itemstack, itemstring, table or nil"); + throw LuaError(L, "Expecting itemstack, itemstring, table or nil"); } } @@ -941,7 +941,7 @@ std::vector read_items(lua_State *L, int index, Server *srv) while (lua_next(L, index)) { s32 key = luaL_checkinteger(L, -2); if (key < 1) { - throw LuaError(NULL, "Invalid inventory list index"); + throw LuaError(L, "Invalid inventory list index"); } if (items.size() < (u32) key) { items.resize(key); diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 90846676..b7dfb178 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -71,7 +71,7 @@ void script_error(lua_State *L) { const char *s = lua_tostring(L, -1); std::string str(s ? s : ""); - throw LuaError(NULL, str); + throw LuaError(L, str); } // Push the list of callbacks (a lua table). diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index db3c13fe..c4912163 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -54,7 +54,7 @@ int ScriptApiDetached::detached_inventory_AllowMove( if(lua_pcall(L, 7, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_move should return a number"); + throw LuaError(L, "allow_move should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -86,7 +86,7 @@ int ScriptApiDetached::detached_inventory_AllowPut( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_put should return a number"); + throw LuaError(L, "allow_put should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -118,7 +118,7 @@ int ScriptApiDetached::detached_inventory_AllowTake( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_take should return a number"); + throw LuaError(L, "allow_take should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp index e15abd40..9513238c 100644 --- a/src/script/cpp_api/s_nodemeta.cpp +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -61,7 +61,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_metadata_inventory_move should" + throw LuaError(L, "allow_metadata_inventory_move should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer @@ -100,7 +100,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_metadata_inventory_put should" + throw LuaError(L, "allow_metadata_inventory_put should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer @@ -139,7 +139,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(NULL, "allow_metadata_inventory_take should" + throw LuaError(L, "allow_metadata_inventory_take should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp index 98320b57..4baf9063 100644 --- a/src/script/cpp_api/s_server.cpp +++ b/src/script/cpp_api/s_server.cpp @@ -33,7 +33,7 @@ bool ScriptApiServer::getAuth(const std::string &playername, getAuthHandler(); lua_getfield(L, -1, "get_auth"); if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(NULL, "Authentication handler missing get_auth"); + throw LuaError(L, "Authentication handler missing get_auth"); lua_pushstring(L, playername.c_str()); if(lua_pcall(L, 1, 1, errorhandler)) scriptError(); @@ -48,13 +48,13 @@ bool ScriptApiServer::getAuth(const std::string &playername, std::string password; bool found = getstringfield(L, -1, "password", password); if(!found) - throw LuaError(NULL, "Authentication handler didn't return password"); + throw LuaError(L, "Authentication handler didn't return password"); if(dst_password) *dst_password = password; lua_getfield(L, -1, "privileges"); if(!lua_istable(L, -1)) - throw LuaError(NULL, "Authentication handler didn't return privilege table"); + throw LuaError(L, "Authentication handler didn't return privilege table"); if(dst_privs) readPrivileges(-1, *dst_privs); lua_pop(L, 1); @@ -74,7 +74,7 @@ void ScriptApiServer::getAuthHandler() } lua_remove(L, -2); // Remove minetest if(lua_type(L, -1) != LUA_TTABLE) - throw LuaError(NULL, "Authentication handler table not valid"); + throw LuaError(L, "Authentication handler table not valid"); } void ScriptApiServer::readPrivileges(int index, std::set &result) @@ -108,7 +108,7 @@ void ScriptApiServer::createAuth(const std::string &playername, lua_getfield(L, -1, "create_auth"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(NULL, "Authentication handler missing create_auth"); + throw LuaError(L, "Authentication handler missing create_auth"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 0, errorhandler)) @@ -128,7 +128,7 @@ bool ScriptApiServer::setPassword(const std::string &playername, lua_getfield(L, -1, "set_password"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(NULL, "Authentication handler missing set_password"); + throw LuaError(L, "Authentication handler missing set_password"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 1, errorhandler)) diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index aaca84c5..240aa045 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -150,16 +150,16 @@ int ModApiCraft::l_register_craft(lua_State *L) if(type == "shaped"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition is missing an output"); + throw LuaError(L, "Crafting definition is missing an output"); int width = 0; std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(NULL, "Crafting definition is missing a recipe" + throw LuaError(L, "Crafting definition is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShaped(L, -1, width, recipe)) - throw LuaError(NULL, "Invalid crafting recipe" + throw LuaError(L, "Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -167,7 +167,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError(L, "Invalid replacements" " (output=\"" + output + "\")"); } @@ -181,17 +181,17 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "shapeless"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition (shapeless)" + throw LuaError(L, "Crafting definition (shapeless)" " is missing an output"); std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(NULL, "Crafting definition (shapeless)" + throw LuaError(L, "Crafting definition (shapeless)" " is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShapeless(L, -1, recipe)) - throw LuaError(NULL, "Invalid crafting recipe" + throw LuaError(L, "Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -199,7 +199,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError(L, "Invalid replacements" " (output=\"" + output + "\")"); } @@ -224,12 +224,12 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "cooking"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition (cooking)" + throw LuaError(L, "Crafting definition (cooking)" " is missing an output"); std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(NULL, "Crafting definition (cooking)" + throw LuaError(L, "Crafting definition (cooking)" " is missing a recipe" " (output=\"" + output + "\")"); @@ -240,7 +240,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError(L, "Invalid replacements" " (cooking output=\"" + output + "\")"); } @@ -254,7 +254,7 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "fuel"){ std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(NULL, "Crafting definition (fuel)" + throw LuaError(L, "Crafting definition (fuel)" " is missing a recipe"); float burntime = getfloatfield_default(L, table, "burntime", 1.0); @@ -264,7 +264,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError(L, "Invalid replacements" " (fuel recipe=\"" + recipe + "\")"); } @@ -274,7 +274,7 @@ int ModApiCraft::l_register_craft(lua_State *L) } else { - throw LuaError(NULL, "Unknown crafting definition type: \"" + type + "\""); + throw LuaError(L, "Unknown crafting definition type: \"" + type + "\""); } lua_pop(L, 1); From 93729b09d5e02ed64ad7322137654c38bf858037 Mon Sep 17 00:00:00 2001 From: Novatux Date: Sat, 15 Mar 2014 15:08:43 +0100 Subject: [PATCH 17/53] Fix sound not being played at the correct place. --- src/game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.cpp b/src/game.cpp index 2b14b2c8..0a9dcfda 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2659,7 +2659,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, } // Update sound listener - sound->updateListener(camera.getCameraNode()->getPosition(), + sound->updateListener(camera.getCameraNode()->getPosition()+intToFloat(camera_offset, BS), v3f(0,0,0), // velocity camera.getDirection(), camera.getCameraNode()->getUpVector()); From 23be6450a115954b281c045aefacbefba6837b6f Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 15 Mar 2014 15:12:11 -0400 Subject: [PATCH 18/53] Make serializeStructToString use an ostringstream --- src/util/serialize.cpp | 69 ++++++++++++++++-------------------------- src/util/serialize.h | 2 +- 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index 069ec538..f05cfcc9 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -385,23 +385,20 @@ fail: } -bool serializeStructToString(std::string *outstr, +bool serializeStructToString(std::string *out, std::string format, void *value) { - char sbuf[2048]; - int sbuflen = sizeof(sbuf) - 1; - sbuf[sbuflen] = 0; + std::ostringstream os; std::string str; - int pos = 0; - size_t fpos; char *f; + size_t strpos; - char *bufpos = (char *)value; + char *bufpos = (char *) value; char *fmtpos, *fmt = &format[0]; while ((f = strtok_r(fmt, ",", &fmtpos))) { fmt = NULL; bool is_unsigned = false; - int width = 0, nprinted = 0; + int width = 0; char valtype = *f; width = (int)strtol(f + 1, &f, 10); @@ -415,79 +412,65 @@ bool serializeStructToString(std::string *outstr, case 'i': if (width == 16) { bufpos += PADDING(bufpos, u16); - nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%u, " : "%d, ", - *((u16 *)bufpos)); + os << *((u16 *) bufpos); bufpos += sizeof(u16); } else if (width == 32) { bufpos += PADDING(bufpos, u32); - nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%u, " : "%d, ", - *((u32 *)bufpos)); + os << *((u32 *) bufpos); bufpos += sizeof(u32); } else if (width == 64) { bufpos += PADDING(bufpos, u64); - nprinted = snprintf(sbuf + pos, sbuflen, - is_unsigned ? "%llu, " : "%lli, ", - (unsigned long long)*((u64 *)bufpos)); + os << *((u64 *) bufpos); bufpos += sizeof(u64); } break; case 'b': bufpos += PADDING(bufpos, bool); - nprinted = snprintf(sbuf + pos, sbuflen, "%s, ", - *((bool *)bufpos) ? "true" : "false"); + os << std::boolalpha << *((bool *) bufpos); bufpos += sizeof(bool); break; case 'f': bufpos += PADDING(bufpos, float); - nprinted = snprintf(sbuf + pos, sbuflen, "%f, ", - *((float *)bufpos)); + os << *((float *) bufpos); bufpos += sizeof(float); break; case 's': bufpos += PADDING(bufpos, std::string *); - str = **((std::string **)bufpos); + str = **((std::string **) bufpos); - fpos = 0; - while ((fpos = str.find('"', fpos)) != std::string::npos) { - str.insert(fpos, 1, '\\'); - fpos += 2; + strpos = 0; + while ((strpos = str.find('"', strpos)) != std::string::npos) { + str.insert(strpos, 1, '\\'); + strpos += 2; } - nprinted = snprintf(sbuf + pos, sbuflen, "\"%s\", ", - (*((std::string **)bufpos))->c_str()); + os << str; bufpos += sizeof(std::string *); break; case 'v': if (width == 2) { bufpos += PADDING(bufpos, v2f); - v2f *v = (v2f *)bufpos; - nprinted = snprintf(sbuf + pos, sbuflen, - "(%f, %f), ", v->X, v->Y); + v2f *v = (v2f *) bufpos; + os << '(' << v->X << ", " << v->Y << ')'; bufpos += sizeof(v2f); } else { bufpos += PADDING(bufpos, v3f); - v3f *v = (v3f *)bufpos; - nprinted = snprintf(sbuf + pos, sbuflen, - "(%f, %f, %f), ", v->X, v->Y, v->Z); + v3f *v = (v3f *) bufpos; + os << '(' << v->X << ", " << v->Y << ", " << v->Z << ')'; bufpos += sizeof(v3f); } break; default: return false; } - if (nprinted < 0) //error, buffer too small - return false; - pos += nprinted; - sbuflen -= nprinted; + os << ", "; } + *out = os.str(); - // this is to trim off the trailing comma - if (pos >= 2) - sbuf[pos - 2] = 0; - - *outstr = sbuf; + // Trim off the trailing comma and space + if (out->size() >= 2) { + out->resize(out->size() - 2); + } return true; } diff --git a/src/util/serialize.h b/src/util/serialize.h index 4c883602..63713f7c 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -403,7 +403,7 @@ std::string deSerializeJsonString(std::istream &is); // Creates a string containing comma delimited values of a struct whose layout is // described by the parameter format -bool serializeStructToString(std::string *outstr, +bool serializeStructToString(std::string *out, std::string format, void *value); // Reads a comma delimited string of values into a struct whose layout is From f8b75555586e0e67d8320a804b9e077d29b96403 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 15 Mar 2014 16:01:06 -0400 Subject: [PATCH 19/53] Revert "Make sure we get a stacktrace for as many lua errors as possible" This reverts commit 362ef5f6ced862daa4733034810d0b07e2ad5d89. Stack tracebacks couldn't be generated in LuaError::LuaError anyway and this caused a second, empty traceback in most cases. In cases where there wasn't annother traceback the stack had already unwound and the traceback was empty. --- src/script/common/c_content.cpp | 4 ++-- src/script/common/c_internal.cpp | 2 +- src/script/cpp_api/s_inventory.cpp | 6 +++--- src/script/cpp_api/s_nodemeta.cpp | 6 +++--- src/script/cpp_api/s_server.cpp | 12 ++++++------ src/script/lua_api/l_craft.cpp | 28 ++++++++++++++-------------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 4730ca14..899e1c53 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -654,7 +654,7 @@ ItemStack read_item(lua_State* L, int index,Server* srv) } else { - throw LuaError(L, "Expecting itemstack, itemstring, table or nil"); + throw LuaError(NULL, "Expecting itemstack, itemstring, table or nil"); } } @@ -941,7 +941,7 @@ std::vector read_items(lua_State *L, int index, Server *srv) while (lua_next(L, index)) { s32 key = luaL_checkinteger(L, -2); if (key < 1) { - throw LuaError(L, "Invalid inventory list index"); + throw LuaError(NULL, "Invalid inventory list index"); } if (items.size() < (u32) key) { items.resize(key); diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index b7dfb178..90846676 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -71,7 +71,7 @@ void script_error(lua_State *L) { const char *s = lua_tostring(L, -1); std::string str(s ? s : ""); - throw LuaError(L, str); + throw LuaError(NULL, str); } // Push the list of callbacks (a lua table). diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index c4912163..db3c13fe 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -54,7 +54,7 @@ int ScriptApiDetached::detached_inventory_AllowMove( if(lua_pcall(L, 7, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_move should return a number"); + throw LuaError(NULL, "allow_move should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -86,7 +86,7 @@ int ScriptApiDetached::detached_inventory_AllowPut( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_put should return a number"); + throw LuaError(NULL, "allow_put should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -118,7 +118,7 @@ int ScriptApiDetached::detached_inventory_AllowTake( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_take should return a number"); + throw LuaError(NULL, "allow_take should return a number"); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp index 9513238c..e15abd40 100644 --- a/src/script/cpp_api/s_nodemeta.cpp +++ b/src/script/cpp_api/s_nodemeta.cpp @@ -61,7 +61,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_move should" + throw LuaError(NULL, "allow_metadata_inventory_move should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer @@ -100,7 +100,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_put should" + throw LuaError(NULL, "allow_metadata_inventory_put should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer @@ -139,7 +139,7 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p, scriptError(); lua_remove(L, errorhandler); // Remove error handler if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_take should" + throw LuaError(NULL, "allow_metadata_inventory_take should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp index 4baf9063..98320b57 100644 --- a/src/script/cpp_api/s_server.cpp +++ b/src/script/cpp_api/s_server.cpp @@ -33,7 +33,7 @@ bool ScriptApiServer::getAuth(const std::string &playername, getAuthHandler(); lua_getfield(L, -1, "get_auth"); if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing get_auth"); + throw LuaError(NULL, "Authentication handler missing get_auth"); lua_pushstring(L, playername.c_str()); if(lua_pcall(L, 1, 1, errorhandler)) scriptError(); @@ -48,13 +48,13 @@ bool ScriptApiServer::getAuth(const std::string &playername, std::string password; bool found = getstringfield(L, -1, "password", password); if(!found) - throw LuaError(L, "Authentication handler didn't return password"); + throw LuaError(NULL, "Authentication handler didn't return password"); if(dst_password) *dst_password = password; lua_getfield(L, -1, "privileges"); if(!lua_istable(L, -1)) - throw LuaError(L, "Authentication handler didn't return privilege table"); + throw LuaError(NULL, "Authentication handler didn't return privilege table"); if(dst_privs) readPrivileges(-1, *dst_privs); lua_pop(L, 1); @@ -74,7 +74,7 @@ void ScriptApiServer::getAuthHandler() } lua_remove(L, -2); // Remove minetest if(lua_type(L, -1) != LUA_TTABLE) - throw LuaError(L, "Authentication handler table not valid"); + throw LuaError(NULL, "Authentication handler table not valid"); } void ScriptApiServer::readPrivileges(int index, std::set &result) @@ -108,7 +108,7 @@ void ScriptApiServer::createAuth(const std::string &playername, lua_getfield(L, -1, "create_auth"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing create_auth"); + throw LuaError(NULL, "Authentication handler missing create_auth"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 0, errorhandler)) @@ -128,7 +128,7 @@ bool ScriptApiServer::setPassword(const std::string &playername, lua_getfield(L, -1, "set_password"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing set_password"); + throw LuaError(NULL, "Authentication handler missing set_password"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 1, errorhandler)) diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index 240aa045..aaca84c5 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -150,16 +150,16 @@ int ModApiCraft::l_register_craft(lua_State *L) if(type == "shaped"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(L, "Crafting definition is missing an output"); + throw LuaError(NULL, "Crafting definition is missing an output"); int width = 0; std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(L, "Crafting definition is missing a recipe" + throw LuaError(NULL, "Crafting definition is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShaped(L, -1, width, recipe)) - throw LuaError(L, "Invalid crafting recipe" + throw LuaError(NULL, "Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -167,7 +167,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" + throw LuaError(NULL, "Invalid replacements" " (output=\"" + output + "\")"); } @@ -181,17 +181,17 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "shapeless"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(L, "Crafting definition (shapeless)" + throw LuaError(NULL, "Crafting definition (shapeless)" " is missing an output"); std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(L, "Crafting definition (shapeless)" + throw LuaError(NULL, "Crafting definition (shapeless)" " is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShapeless(L, -1, recipe)) - throw LuaError(L, "Invalid crafting recipe" + throw LuaError(NULL, "Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -199,7 +199,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" + throw LuaError(NULL, "Invalid replacements" " (output=\"" + output + "\")"); } @@ -224,12 +224,12 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "cooking"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(L, "Crafting definition (cooking)" + throw LuaError(NULL, "Crafting definition (cooking)" " is missing an output"); std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(L, "Crafting definition (cooking)" + throw LuaError(NULL, "Crafting definition (cooking)" " is missing a recipe" " (output=\"" + output + "\")"); @@ -240,7 +240,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" + throw LuaError(NULL, "Invalid replacements" " (cooking output=\"" + output + "\")"); } @@ -254,7 +254,7 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "fuel"){ std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(L, "Crafting definition (fuel)" + throw LuaError(NULL, "Crafting definition (fuel)" " is missing a recipe"); float burntime = getfloatfield_default(L, table, "burntime", 1.0); @@ -264,7 +264,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" + throw LuaError(NULL, "Invalid replacements" " (fuel recipe=\"" + recipe + "\")"); } @@ -274,7 +274,7 @@ int ModApiCraft::l_register_craft(lua_State *L) } else { - throw LuaError(L, "Unknown crafting definition type: \"" + type + "\""); + throw LuaError(NULL, "Unknown crafting definition type: \"" + type + "\""); } lua_pop(L, 1); From 31fe72dbac3d53e8da21ef116ccf99febbc5196e Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 15 Mar 2014 16:28:59 -0400 Subject: [PATCH 20/53] Remove lua_State parameter from LuaError::LuaError --- src/script/common/c_content.cpp | 4 ++-- src/script/common/c_internal.cpp | 2 +- src/script/common/c_types.cpp | 7 ------- src/script/common/c_types.h | 9 +-------- src/script/cpp_api/s_base.cpp | 5 +++-- src/script/cpp_api/s_inventory.cpp | 6 +++--- src/script/cpp_api/s_nodemeta.cpp | 6 +++--- src/script/cpp_api/s_server.cpp | 12 ++++++------ src/script/lua_api/l_base.h | 2 +- src/script/lua_api/l_craft.cpp | 28 ++++++++++++++-------------- src/script/lua_api/l_item.cpp | 4 ++-- src/script/lua_api/l_noise.cpp | 4 ++-- src/script/lua_api/l_object.cpp | 2 +- 13 files changed, 39 insertions(+), 52 deletions(-) diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 899e1c53..2898d28a 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -654,7 +654,7 @@ ItemStack read_item(lua_State* L, int index,Server* srv) } else { - throw LuaError(NULL, "Expecting itemstack, itemstring, table or nil"); + throw LuaError("Expecting itemstack, itemstring, table or nil"); } } @@ -941,7 +941,7 @@ std::vector read_items(lua_State *L, int index, Server *srv) while (lua_next(L, index)) { s32 key = luaL_checkinteger(L, -2); if (key < 1) { - throw LuaError(NULL, "Invalid inventory list index"); + throw LuaError("Invalid inventory list index"); } if (items.size() < (u32) key) { items.resize(key); diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp index 90846676..4263dec9 100644 --- a/src/script/common/c_internal.cpp +++ b/src/script/common/c_internal.cpp @@ -71,7 +71,7 @@ void script_error(lua_State *L) { const char *s = lua_tostring(L, -1); std::string str(s ? s : ""); - throw LuaError(NULL, str); + throw LuaError(str); } // Push the list of callbacks (a lua table). diff --git a/src/script/common/c_types.cpp b/src/script/common/c_types.cpp index 6ffad1cb..e832ff2a 100644 --- a/src/script/common/c_types.cpp +++ b/src/script/common/c_types.cpp @@ -23,13 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_internal.h" #include "itemdef.h" -LuaError::LuaError(lua_State *L, const std::string &s) : - ServerError(s) -{ - if (L) { - m_s += '\n' + script_get_backtrace(L); - } -} struct EnumString es_ItemType[] = { diff --git a/src/script/common/c_types.h b/src/script/common/c_types.h index 709d4f34..70647073 100644 --- a/src/script/common/c_types.h +++ b/src/script/common/c_types.h @@ -55,14 +55,7 @@ public: class LuaError : public ServerError { public: - LuaError(lua_State *L, const std::string &s); - - virtual ~LuaError() throw() - {} - virtual const char * what() const throw() - { - return m_s.c_str(); - } + LuaError(const std::string &s) : ServerError(s) {} }; diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e28a34ee..932cc501 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -151,13 +151,14 @@ void ScriptApiBase::realityCheck() if(top >= 30){ dstream<<"Stack is over 30:"< &result) @@ -108,7 +108,7 @@ void ScriptApiServer::createAuth(const std::string &playername, lua_getfield(L, -1, "create_auth"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(NULL, "Authentication handler missing create_auth"); + throw LuaError("Authentication handler missing create_auth"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 0, errorhandler)) @@ -128,7 +128,7 @@ bool ScriptApiServer::setPassword(const std::string &playername, lua_getfield(L, -1, "set_password"); lua_remove(L, -2); // Remove auth handler if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(NULL, "Authentication handler missing set_password"); + throw LuaError("Authentication handler missing set_password"); lua_pushstring(L, playername.c_str()); lua_pushstring(L, password.c_str()); if(lua_pcall(L, 2, 1, errorhandler)) diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h index 694ce5a1..debbcd09 100644 --- a/src/script/lua_api/l_base.h +++ b/src/script/lua_api/l_base.h @@ -48,7 +48,7 @@ protected: ScriptApiBase *scriptIface = getScriptApiBase(L); T *scriptIfaceDowncast = dynamic_cast(scriptIface); if (!scriptIfaceDowncast) { - throw LuaError(NULL, "Requested unavailable ScriptApi - core engine bug!"); + throw LuaError("Requested unavailable ScriptApi - core engine bug!"); } return scriptIfaceDowncast; } diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index aaca84c5..8f8efbfb 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -150,16 +150,16 @@ int ModApiCraft::l_register_craft(lua_State *L) if(type == "shaped"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition is missing an output"); + throw LuaError("Crafting definition is missing an output"); int width = 0; std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(NULL, "Crafting definition is missing a recipe" + throw LuaError("Crafting definition is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShaped(L, -1, width, recipe)) - throw LuaError(NULL, "Invalid crafting recipe" + throw LuaError("Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -167,7 +167,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError("Invalid replacements" " (output=\"" + output + "\")"); } @@ -181,17 +181,17 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "shapeless"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition (shapeless)" + throw LuaError("Crafting definition (shapeless)" " is missing an output"); std::vector recipe; lua_getfield(L, table, "recipe"); if(lua_isnil(L, -1)) - throw LuaError(NULL, "Crafting definition (shapeless)" + throw LuaError("Crafting definition (shapeless)" " is missing a recipe" " (output=\"" + output + "\")"); if(!readCraftRecipeShapeless(L, -1, recipe)) - throw LuaError(NULL, "Invalid crafting recipe" + throw LuaError("Invalid crafting recipe" " (output=\"" + output + "\")"); CraftReplacements replacements; @@ -199,7 +199,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError("Invalid replacements" " (output=\"" + output + "\")"); } @@ -224,12 +224,12 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "cooking"){ std::string output = getstringfield_default(L, table, "output", ""); if(output == "") - throw LuaError(NULL, "Crafting definition (cooking)" + throw LuaError("Crafting definition (cooking)" " is missing an output"); std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(NULL, "Crafting definition (cooking)" + throw LuaError("Crafting definition (cooking)" " is missing a recipe" " (output=\"" + output + "\")"); @@ -240,7 +240,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError("Invalid replacements" " (cooking output=\"" + output + "\")"); } @@ -254,7 +254,7 @@ int ModApiCraft::l_register_craft(lua_State *L) else if(type == "fuel"){ std::string recipe = getstringfield_default(L, table, "recipe", ""); if(recipe == "") - throw LuaError(NULL, "Crafting definition (fuel)" + throw LuaError("Crafting definition (fuel)" " is missing a recipe"); float burntime = getfloatfield_default(L, table, "burntime", 1.0); @@ -264,7 +264,7 @@ int ModApiCraft::l_register_craft(lua_State *L) if(!lua_isnil(L, -1)) { if(!readCraftReplacements(L, -1, replacements)) - throw LuaError(NULL, "Invalid replacements" + throw LuaError("Invalid replacements" " (fuel recipe=\"" + recipe + "\")"); } @@ -274,7 +274,7 @@ int ModApiCraft::l_register_craft(lua_State *L) } else { - throw LuaError(NULL, "Unknown crafting definition type: \"" + type + "\""); + throw LuaError("Unknown crafting definition type: \"" + type + "\""); } lua_pop(L, 1); diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 4b5c8979..094d0bb2 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -470,7 +470,7 @@ int ModApiItemMod::l_register_item_raw(lua_State *L) name = lua_tostring(L, -1); verbosestream<<"register_item_raw: "<set(f.name, f); if(id > MAX_REGISTERED_CONTENT){ - throw LuaError(NULL, "Number of registerable nodes (" + throw LuaError("Number of registerable nodes (" + itos(MAX_REGISTERED_CONTENT+1) + ") exceeded (" + name + ")"); } diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index 4ca9992a..263ecfd6 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -330,10 +330,10 @@ int LuaPseudoRandom::l_next(lua_State *L) max = luaL_checkinteger(L, 3); if(max < min){ errorstream<<"PseudoRandom.next(): max="< 32767/5) - throw LuaError(NULL, "PseudoRandom.next() max-min is not 32767" + throw LuaError("PseudoRandom.next() max-min is not 32767" " and is > 32768/5. This is disallowed due to" " the bad random distribution the" " implementation would otherwise make."); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 059496c3..90af51cc 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1120,7 +1120,7 @@ int ObjectRef::l_set_sky(lua_State *L) } if (type == "skybox" && params.size() != 6) - throw LuaError(L, "skybox expects 6 textures"); + throw LuaError("skybox expects 6 textures"); if (!getServer(L)->setSky(player, bgcolor, type, params)) return 0; From f3d83a4516eb9c6658a7c3e07bf1b7d4f4996bef Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 15 Mar 2014 17:20:52 -0400 Subject: [PATCH 21/53] Add more informative error messages for inventory and item method errors --- src/script/cpp_api/s_inventory.cpp | 6 ++-- src/script/cpp_api/s_item.cpp | 45 +++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp index 835c0818..dd7e2651 100644 --- a/src/script/cpp_api/s_inventory.cpp +++ b/src/script/cpp_api/s_inventory.cpp @@ -54,7 +54,7 @@ int ScriptApiDetached::detached_inventory_AllowMove( if(lua_pcall(L, 7, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError("allow_move should return a number"); + throw LuaError("allow_move should return a number. name=" + name); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -86,7 +86,7 @@ int ScriptApiDetached::detached_inventory_AllowPut( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError("allow_put should return a number"); + throw LuaError("allow_put should return a number. name=" + name); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; @@ -118,7 +118,7 @@ int ScriptApiDetached::detached_inventory_AllowTake( if(lua_pcall(L, 5, 1, errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) - throw LuaError("allow_take should return a number"); + throw LuaError("allow_take should return a number. name=" + name); int ret = luaL_checkinteger(L, -1); lua_pop(L, 2); // Pop integer and error handler return ret; diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 49729e57..41413d61 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -47,8 +47,13 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item, pushFloatPos(L, pos); if(lua_pcall(L, 3, 1, errorhandler)) scriptError(); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L,-1, getServer()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } lua_pop(L, 2); // Pop item and error handler return true; } @@ -71,8 +76,13 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, pushPointedThing(pointed); if(lua_pcall(L, 3, 1, errorhandler)) scriptError(); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L,-1, getServer()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } lua_pop(L, 2); // Pop item and error handler return true; } @@ -95,8 +105,13 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, pushPointedThing(pointed); if(lua_pcall(L, 3, 1, errorhandler)) scriptError(); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L,-1, getServer()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } lua_pop(L, 2); // Pop item and error handler return true; } @@ -123,8 +138,13 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, InvRef::create(L, craft_inv); if(lua_pcall(L, 4, 1, errorhandler)) scriptError(); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L,-1, getServer()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } lua_pop(L, 2); // Pop item and error handler return true; } @@ -151,8 +171,13 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, InvRef::create(L, craft_inv); if(lua_pcall(L, 4, 1, errorhandler)) scriptError(); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L,-1, getServer()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } lua_pop(L, 2); // Pop item and error handler return true; } From 0dc1aec50940140e28f434c524296e284e73d623 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Fri, 21 Mar 2014 01:32:00 +0100 Subject: [PATCH 22/53] Normal maps generation on the fly. Parallax mapping with slope information. Overriding normal maps. --- builtin/mainmenu.lua | 28 ++- .../shaders/alpha_shader/opengl_fragment.glsl | 181 +++++++++------- .../shaders/alpha_shader/opengl_vertex.glsl | 40 ++-- .../leaves_shader/opengl_fragment.glsl | 154 +++++++++----- .../shaders/leaves_shader/opengl_vertex.glsl | 21 +- .../liquids_shader/opengl_fragment.glsl | 149 ++++++++----- .../shaders/liquids_shader/opengl_vertex.glsl | 67 +++++- .../plants_shader/opengl_fragment.glsl | 148 ++++++++----- .../shaders/plants_shader/opengl_vertex.glsl | 21 +- .../solids_shader/opengl_fragment.glsl | 200 ++++++++++-------- .../shaders/solids_shader/opengl_vertex.glsl | 40 ++-- minetest.conf.example | 8 + src/defaultsettings.cpp | 7 +- src/game.cpp | 5 +- src/mapblock_mesh.cpp | 56 +++-- src/shader.cpp | 44 +++- 16 files changed, 735 insertions(+), 434 deletions(-) diff --git a/builtin/mainmenu.lua b/builtin/mainmenu.lua index ad8b37ee..e9c8e813 100644 --- a/builtin/mainmenu.lua +++ b/builtin/mainmenu.lua @@ -723,6 +723,9 @@ function tabbuilder.handle_settings_buttons(fields) if fields["cb_parallax"] then engine.setting_set("enable_parallax_occlusion", fields["cb_parallax"]) end + if fields["cb_generate_normalmaps"] then + engine.setting_set("generate_normalmaps", fields["cb_generate_normalmaps"]) + end if fields["cb_waving_water"] then engine.setting_set("enable_waving_water", fields["cb_waving_water"]) end @@ -1010,27 +1013,30 @@ function tabbuilder.tab_settings() .. dump(engine.setting_getbool("enable_shaders")) .. "]".. "button[1,4.5;2.25,0.5;btn_change_keys;".. fgettext("Change keys") .. "]" -if engine.setting_getbool("enable_shaders") then - tab_string = tab_string .. + if engine.setting_getbool("enable_shaders") then + tab_string = tab_string .. "checkbox[8,0.5;cb_bumpmapping;".. fgettext("Bumpmapping") .. ";" .. dump(engine.setting_getbool("enable_bumpmapping")) .. "]".. "checkbox[8,1.0;cb_parallax;".. fgettext("Parallax Occlusion") .. ";" .. dump(engine.setting_getbool("enable_parallax_occlusion")) .. "]".. - "checkbox[8,1.5;cb_waving_water;".. fgettext("Waving Water") .. ";" + "checkbox[8,1.5;cb_generate_normalmaps;".. fgettext("Generate Normalmaps") .. ";" + .. dump(engine.setting_getbool("generate_normalmaps")) .. "]".. + "checkbox[8,2.0;cb_waving_water;".. fgettext("Waving Water") .. ";" .. dump(engine.setting_getbool("enable_waving_water")) .. "]".. - "checkbox[8,2.0;cb_waving_leaves;".. fgettext("Waving Leaves") .. ";" + "checkbox[8,2.5;cb_waving_leaves;".. fgettext("Waving Leaves") .. ";" .. dump(engine.setting_getbool("enable_waving_leaves")) .. "]".. - "checkbox[8,2.5;cb_waving_plants;".. fgettext("Waving Plants") .. ";" + "checkbox[8,3.0;cb_waving_plants;".. fgettext("Waving Plants") .. ";" .. dump(engine.setting_getbool("enable_waving_plants")) .. "]" -else - tab_string = tab_string .. + else + tab_string = tab_string .. "textlist[8.33,0.7;4,1;;#888888" .. fgettext("Bumpmapping") .. ";0;true]" .. "textlist[8.33,1.2;4,1;;#888888" .. fgettext("Parallax Occlusion") .. ";0;true]" .. - "textlist[8.33,1.7;4,1;;#888888" .. fgettext("Waving Water") .. ";0;true]" .. - "textlist[8.33,2.2;4,1;;#888888" .. fgettext("Waving Leaves") .. ";0;true]" .. - "textlist[8.33,2.7;4,1;;#888888" .. fgettext("Waving Plants") .. ";0;true]" + "textlist[8.33,1.7;4,1;;#888888" .. fgettext("Generate Normalmaps") .. ";0;true]" .. + "textlist[8.33,2.2;4,1;;#888888" .. fgettext("Waving Water") .. ";0;true]" .. + "textlist[8.33,2.7;4,1;;#888888" .. fgettext("Waving Leaves") .. ";0;true]" .. + "textlist[8.33,3.2;4,1;;#888888" .. fgettext("Waving Plants") .. ";0;true]" end -return tab_string + return tab_string end -------------------------------------------------------------------------------- diff --git a/client/shaders/alpha_shader/opengl_fragment.glsl b/client/shaders/alpha_shader/opengl_fragment.glsl index 6ed00be2..4359a8c8 100644 --- a/client/shaders/alpha_shader/opengl_fragment.glsl +++ b/client/shaders/alpha_shader/opengl_fragment.glsl @@ -1,71 +1,110 @@ -uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D useNormalmap; - -uniform vec4 skyBgColor; -uniform float fogDistance; -uniform vec3 eyePosition; - -varying vec3 vPosition; -varying vec3 eyeVec; - -#ifdef ENABLE_PARALLAX_OCCLUSION -varying vec3 tsEyeVec; -#endif - -const float e = 2.718281828459; - -void main (void) -{ - vec3 color; - vec2 uv = gl_TexCoord[0].st; - -#ifdef USE_NORMALMAPS - float use_normalmap = texture2D(useNormalmap,vec2(1.0,1.0)).r; -#endif - -#ifdef ENABLE_PARALLAX_OCCLUSION - float height; - vec2 tsEye = vec2(tsEyeVec.x,-tsEyeVec.y); - - if (use_normalmap > 0.0) { - float map_height = texture2D(normalTexture, uv).a; - if (map_height < 1.0){ - float height = PARALLAX_OCCLUSION_SCALE * map_height - PARALLAX_OCCLUSION_BIAS; - uv = uv + height * tsEye; - } - } -#endif - -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap > 0.0) { - vec3 base = texture2D(baseTexture, uv).rgb; - vec3 vVec = normalize(eyeVec); - vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0); - vec3 R = reflect(-vVec, bump); - vec3 lVec = normalize(vVec); - float diffuse = max(dot(lVec, bump), 0.0); - float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0); - color = mix (base,diffuse*base,1.0) + 0.1 * specular * diffuse; - } else { - color = texture2D(baseTexture, uv).rgb; - } -#else - color = texture2D(baseTexture, uv).rgb; -#endif - - float alpha = texture2D(baseTexture, uv).a; - vec4 col = vec4(color.r, color.g, color.b, alpha); - col *= gl_Color; - col = col * col; // SRGB -> Linear - col *= 1.8; - col.r = 1.0 - exp(1.0 - col.r) / e; - col.g = 1.0 - exp(1.0 - col.g) / e; - col.b = 1.0 - exp(1.0 - col.b) / e; - col = sqrt(col); // Linear -> SRGB - if(fogDistance != 0.0){ - float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); - col = mix(col, skyBgColor, d); - } - gl_FragColor = vec4(col.r, col.g, col.b, alpha); -} +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D useNormalmap; + +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 tsEyeVec; +varying vec3 lightVec; +varying vec3 tsLightVec; + +bool normalTexturePresent = false; + +const float e = 2.718281828459; + +float intensity (vec3 color){ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height (vec2 uv){ + return intensity(texture2D(baseTexture,uv).rgb); +} + +vec4 get_normal_map(vec2 uv){ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 -1.0); + bump.y = -bump.y; + return bump; +} + +void main (void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + +#ifdef USE_NORMALMAPS + if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ + normalTexturePresent = true; + } +#endif + +#ifdef ENABLE_PARALLAX_OCCLUSION + if (normalTexturePresent){ + vec3 tsEye = normalize(tsEyeVec); + float height = PARALLAX_OCCLUSION_SCALE * texture2D(normalTexture, uv).a - PARALLAX_OCCLUSION_BIAS; + uv = uv + texture2D(normalTexture, uv).z * height * vec2(tsEye.x,-tsEye.y); + } +#endif + +#ifdef USE_NORMALMAPS + if (normalTexturePresent){ + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#ifdef GENERATE_NORMALMAPS + if (use_normalmap == false){ + float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y)); + float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP)); + float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0); + use_normalmap = true; + } +#endif + +vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap){ + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5); + float diffuse = dot(E,bump.xyz); + color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + vec4 col = vec4(color.rgb, base.a); + col = col * col; // SRGB -> Linear + col *= 1.8; + col.r = 1.0 - exp(1.0 - col.r) / e; + col.g = 1.0 - exp(1.0 - col.g) / e; + col.b = 1.0 - exp(1.0 - col.b) / e; + col = sqrt(col); // Linear -> SRGB + col *= gl_Color; + if(fogDistance != 0.0){ + float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); + col = mix(col, skyBgColor, d); + } + gl_FragColor = vec4(col.rgb, base.a); +} diff --git a/client/shaders/alpha_shader/opengl_vertex.glsl b/client/shaders/alpha_shader/opengl_vertex.glsl index e359955d..356ba2eb 100644 --- a/client/shaders/alpha_shader/opengl_vertex.glsl +++ b/client/shaders/alpha_shader/opengl_vertex.glsl @@ -1,27 +1,33 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform mat4 mWorld; + uniform float dayNightRatio; uniform vec3 eyePosition; varying vec3 vPosition; -varying vec3 eyeVec; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; -#ifdef ENABLE_PARALLAX_OCCLUSION varying vec3 tsEyeVec; -#endif +varying vec3 tsLightVec; + +const float BS = 10.0; void main(void) { + gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = mWorldViewProj * gl_Vertex; - vPosition = (mWorldViewProj * gl_Vertex).xyz; - eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + vPosition = gl_Position.xyz; + worldPosition = (mWorld * gl_Vertex).xyz; + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); -#ifdef ENABLE_PARALLAX_OCCLUSION - vec3 normal,tangent,binormal; + vec3 normal, tangent, binormal; normal = normalize(gl_NormalMatrix * gl_Normal); - if (gl_Normal.x > 0.5) { // 1.0, 0.0, 0.0 tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0)); @@ -47,25 +53,20 @@ void main(void) tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0)); binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); } - mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x, tangent.y, binormal.y, normal.y, tangent.z, binormal.z, normal.z); - tsEyeVec = normalize(eyeVec * tbnMatrix); -#endif + lightVec = sunPosition - worldPosition; + tsLightVec = lightVec * tbnMatrix; + eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + tsEyeVec = eyeVec * tbnMatrix; vec4 color; - //color = vec4(1.0, 1.0, 1.0, 1.0); - float day = gl_Color.r; float night = gl_Color.g; float light_source = gl_Color.b; - /*color.r = mix(night, day, dayNightRatio); - color.g = color.r; - color.b = color.r;*/ - float rg = mix(night, day, dayNightRatio); rg += light_source * 2.5; // Make light sources brighter float b = rg; @@ -90,13 +91,8 @@ void main(void) color = color * color; // SRGB -> Linear if(gl_Normal.y <= 0.5) color *= 0.6; - //color *= 0.7; color = sqrt(color); // Linear -> SRGB - color.a = gl_Color.a; gl_FrontColor = gl_BackColor = color; - - gl_TexCoord[0] = gl_MultiTexCoord0; - } diff --git a/client/shaders/leaves_shader/opengl_fragment.glsl b/client/shaders/leaves_shader/opengl_fragment.glsl index 31981f9b..1db79807 100644 --- a/client/shaders/leaves_shader/opengl_fragment.glsl +++ b/client/shaders/leaves_shader/opengl_fragment.glsl @@ -1,54 +1,100 @@ -uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D useNormalmap; - -uniform vec4 skyBgColor; -uniform float fogDistance; -uniform vec3 eyePosition; - -varying vec3 vPosition; -varying vec3 eyeVec; - -const float e = 2.718281828459; - -void main (void) -{ - vec3 color; - vec2 uv = gl_TexCoord[0].st; - -#ifdef USE_NORMALMAPS - float use_normalmap = texture2D(useNormalmap,vec2(1.0,1.0)).r; -#endif - -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap > 0.0) { - vec3 base = texture2D(baseTexture, uv).rgb; - vec3 vVec = normalize(eyeVec); - vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0); - vec3 R = reflect(-vVec, bump); - vec3 lVec = normalize(vVec); - float diffuse = max(dot(lVec, bump), 0.0); - float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0); - color = mix (base,diffuse*base,1.0) + 0.1 * specular * diffuse; - } else { - color = texture2D(baseTexture, uv).rgb; - } -#else - color = texture2D(baseTexture, uv).rgb; -#endif - - float alpha = texture2D(baseTexture, uv).a; - vec4 col = vec4(color.r, color.g, color.b, alpha); - col *= gl_Color; - col = col * col; // SRGB -> Linear - col *= 1.8; - col.r = 1.0 - exp(1.0 - col.r) / e; - col.g = 1.0 - exp(1.0 - col.g) / e; - col.b = 1.0 - exp(1.0 - col.b) / e; - col = sqrt(col); // Linear -> SRGB - if(fogDistance != 0.0){ - float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); - col = mix(col, skyBgColor, d); - } - gl_FragColor = vec4(col.r, col.g, col.b, alpha); -} +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D useNormalmap; + +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; + +bool normalTexturePresent = false; + +const float e = 2.718281828459; + +float intensity (vec3 color){ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height (vec2 uv){ + return intensity(texture2D(baseTexture,uv).rgb); +} + +vec4 get_normal_map(vec2 uv){ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 -1.0); + bump.y = -bump.y; + return bump; +} + +void main (void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + +#ifdef USE_NORMALMAPS + if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ + normalTexturePresent = true; + } +#endif + +#ifdef USE_NORMALMAPS + if (normalTexturePresent){ + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#ifdef GENERATE_NORMALMAPS + if (use_normalmap == false){ + float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y)); + float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP)); + float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0); + use_normalmap = true; + } +#endif + +vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap){ + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5); + float diffuse = dot(E,bump.xyz); + color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + vec4 col = vec4(color.rgb, base.a); + col = col * col; // SRGB -> Linear + col *= 1.8; + col.r = 1.0 - exp(1.0 - col.r) / e; + col.g = 1.0 - exp(1.0 - col.g) / e; + col.b = 1.0 - exp(1.0 - col.b) / e; + col = sqrt(col); // Linear -> SRGB + col *= gl_Color; + if(fogDistance != 0.0){ + float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); + col = mix(col, skyBgColor, d); + } + gl_FragColor = vec4(col.rgb, base.a); +} diff --git a/client/shaders/leaves_shader/opengl_vertex.glsl b/client/shaders/leaves_shader/opengl_vertex.glsl index 3702b1b5..30ad00b8 100644 --- a/client/shaders/leaves_shader/opengl_vertex.glsl +++ b/client/shaders/leaves_shader/opengl_vertex.glsl @@ -1,13 +1,20 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform mat4 mWorld; + uniform float dayNightRatio; uniform float animationTimer; uniform vec3 eyePosition; varying vec3 vPosition; +varying vec3 worldPosition; + varying vec3 eyeVec; +varying vec3 lightVec; + +const float BS = 10.0; #ifdef ENABLE_WAVING_LEAVES float smoothCurve( float x ) { @@ -27,7 +34,7 @@ void main(void) #ifdef ENABLE_WAVING_LEAVES vec4 pos = gl_Vertex; - vec4 pos2 = mTransWorld*gl_Vertex; + vec4 pos2 = mWorld*gl_Vertex; pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4; pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2; pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4; @@ -36,10 +43,13 @@ void main(void) gl_Position = mWorldViewProj * gl_Vertex; #endif - vPosition = (mWorldViewProj * gl_Vertex).xyz; + vPosition = gl_Position.xyz; + worldPosition = (mWorld * gl_Vertex).xyz; + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); + lightVec = sunPosition - worldPosition; eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; - + vec4 color; //color = vec4(1.0, 1.0, 1.0, 1.0); @@ -75,13 +85,8 @@ void main(void) color = color * color; // SRGB -> Linear if(gl_Normal.y <= 0.5) color *= 0.6; - //color *= 0.7; color = sqrt(color); // Linear -> SRGB - color.a = gl_Color.a; gl_FrontColor = gl_BackColor = color; - - gl_TexCoord[0] = gl_MultiTexCoord0; - } diff --git a/client/shaders/liquids_shader/opengl_fragment.glsl b/client/shaders/liquids_shader/opengl_fragment.glsl index cab8d8e0..e4082259 100644 --- a/client/shaders/liquids_shader/opengl_fragment.glsl +++ b/client/shaders/liquids_shader/opengl_fragment.glsl @@ -1,54 +1,95 @@ -uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D useNormalmap; - -uniform vec4 skyBgColor; -uniform float fogDistance; -uniform vec3 eyePosition; - -varying vec3 vPosition; -varying vec3 eyeVec; - -const float e = 2.718281828459; - -void main (void) -{ - vec3 color; - vec2 uv = gl_TexCoord[0].st; - -#ifdef USE_NORMALMAPS - float use_normalmap = texture2D(useNormalmap,vec2(1.0,1.0)).r; -#endif - -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap > 0.0) { - vec3 base = texture2D(baseTexture, uv).rgb; - vec3 vVec = normalize(eyeVec); - vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0); - vec3 R = reflect(-vVec, bump); - vec3 lVec = normalize(vVec); - float diffuse = max(dot(vec3(-1.0, -0.4, 0.5), bump), 0.0); - float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0); - color = mix (base,diffuse*base,1.0) + 0.1 * specular * diffuse; - } else { - color = texture2D(baseTexture, uv).rgb; - } -#else - color = texture2D(baseTexture, uv).rgb; -#endif - - float alpha = gl_Color.a; - vec4 col = vec4(color.r, color.g, color.b, alpha); - col *= gl_Color; - col = col * col; // SRGB -> Linear - col *= 1.8; - col.r = 1.0 - exp(1.0 - col.r) / e; - col.g = 1.0 - exp(1.0 - col.g) / e; - col.b = 1.0 - exp(1.0 - col.b) / e; - col = sqrt(col); // Linear -> SRGB - if(fogDistance != 0.0){ - float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); - alpha = mix(alpha, 0.0, d); - } - gl_FragColor = vec4(col.r, col.g, col.b, alpha); -} +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D useNormalmap; + +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 tsEyeVec; +varying vec3 lightVec; +varying vec3 tsLightVec; + +const float e = 2.718281828459; + +float intensity (vec3 color){ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height (vec2 uv){ + return intensity(texture2D(baseTexture,uv).rgb); +} + +vec4 get_normal_map(vec2 uv){ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 -1.0); + bump.y = -bump.y; + return bump; +} + +void main (void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + +#ifdef USE_NORMALMAPS + if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#ifdef GENERATE_NORMALMAPS + if (use_normalmap == false){ + float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y)); + float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP)); + float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0); + use_normalmap = true; + } +#endif + +vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap){ + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5); + float diffuse = dot(E,bump.xyz); + color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + float alpha = gl_Color.a; + vec4 col = vec4(color.rgb, alpha); + col = col * col; // SRGB -> Linear + col *= 1.8; + col.r = 1.0 - exp(1.0 - col.r) / e; + col.g = 1.0 - exp(1.0 - col.g) / e; + col.b = 1.0 - exp(1.0 - col.b) / e; + col = sqrt(col); // Linear -> SRGB + col *= gl_Color; + if(fogDistance != 0.0){ + float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); + alpha = mix(alpha, 0.0, d); + } + gl_FragColor = vec4(color.rgb, alpha); +} diff --git a/client/shaders/liquids_shader/opengl_vertex.glsl b/client/shaders/liquids_shader/opengl_vertex.glsl index e8f18582..9d64ce4e 100644 --- a/client/shaders/liquids_shader/opengl_vertex.glsl +++ b/client/shaders/liquids_shader/opengl_vertex.glsl @@ -1,40 +1,84 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform mat4 mWorld; + uniform float dayNightRatio; uniform float animationTimer; uniform vec3 eyePosition; varying vec3 vPosition; +varying vec3 worldPosition; + varying vec3 eyeVec; +varying vec3 lightVec; + +varying vec3 tsEyeVec; +varying vec3 tsLightVec; + +const float BS = 10.0; void main(void) { + gl_TexCoord[0] = gl_MultiTexCoord0; + #ifdef ENABLE_WAVING_WATER vec4 pos2 = gl_Vertex; pos2.y -= 2.0; pos2.y -= sin (pos2.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT + sin ((pos2.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT; gl_Position = mWorldViewProj * pos2; + vPosition = gl_Position.xyz; #else gl_Position = mWorldViewProj * gl_Vertex; + vPosition = gl_Position.xyz; #endif + worldPosition = (mWorld * gl_Vertex).xyz; + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); + + vec3 normal, tangent, binormal; + normal = normalize(gl_NormalMatrix * gl_Normal); + if (gl_Normal.x > 0.5) { + // 1.0, 0.0, 0.0 + tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); + } else if (gl_Normal.x < -0.5) { + // -1.0, 0.0, 0.0 + tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); + } else if (gl_Normal.y > 0.5) { + // 0.0, 1.0, 0.0 + tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0)); + } else if (gl_Normal.y < -0.5) { + // 0.0, -1.0, 0.0 + tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0)); + } else if (gl_Normal.z > 0.5) { + // 0.0, 0.0, 1.0 + tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); + } else if (gl_Normal.z < -0.5) { + // 0.0, 0.0, -1.0 + tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0)); + binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); + } + mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x, + tangent.y, binormal.y, normal.y, + tangent.z, binormal.z, normal.z); + + lightVec = sunPosition - worldPosition; + tsLightVec = lightVec * tbnMatrix; eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; - vPosition = (mWorldViewProj * gl_Vertex).xyz; + tsEyeVec = eyeVec * tbnMatrix; vec4 color; - //color = vec4(1.0, 1.0, 1.0, 1.0); - float day = gl_Color.r; float night = gl_Color.g; float light_source = gl_Color.b; - /*color.r = mix(night, day, dayNightRatio); - color.g = color.r; - color.b = color.r;*/ - float rg = mix(night, day, dayNightRatio); rg += light_source * 2.5; // Make light sources brighter float b = rg; @@ -54,10 +98,13 @@ void main(void) color.r = clamp(rg,0.0,1.0); color.g = clamp(rg,0.0,1.0); color.b = clamp(b,0.0,1.0); + + // Make sides and bottom darker than the top + color = color * color; // SRGB -> Linear + if(gl_Normal.y <= 0.5) + color *= 0.6; + color = sqrt(color); // Linear -> SRGB color.a = gl_Color.a; gl_FrontColor = gl_BackColor = color; - - gl_TexCoord[0] = gl_MultiTexCoord0; - } diff --git a/client/shaders/plants_shader/opengl_fragment.glsl b/client/shaders/plants_shader/opengl_fragment.glsl index 31981f9b..817530a8 100644 --- a/client/shaders/plants_shader/opengl_fragment.glsl +++ b/client/shaders/plants_shader/opengl_fragment.glsl @@ -1,54 +1,94 @@ -uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D useNormalmap; - -uniform vec4 skyBgColor; -uniform float fogDistance; -uniform vec3 eyePosition; - -varying vec3 vPosition; -varying vec3 eyeVec; - -const float e = 2.718281828459; - -void main (void) -{ - vec3 color; - vec2 uv = gl_TexCoord[0].st; - -#ifdef USE_NORMALMAPS - float use_normalmap = texture2D(useNormalmap,vec2(1.0,1.0)).r; -#endif - -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap > 0.0) { - vec3 base = texture2D(baseTexture, uv).rgb; - vec3 vVec = normalize(eyeVec); - vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0); - vec3 R = reflect(-vVec, bump); - vec3 lVec = normalize(vVec); - float diffuse = max(dot(lVec, bump), 0.0); - float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0); - color = mix (base,diffuse*base,1.0) + 0.1 * specular * diffuse; - } else { - color = texture2D(baseTexture, uv).rgb; - } -#else - color = texture2D(baseTexture, uv).rgb; -#endif - - float alpha = texture2D(baseTexture, uv).a; - vec4 col = vec4(color.r, color.g, color.b, alpha); - col *= gl_Color; - col = col * col; // SRGB -> Linear - col *= 1.8; - col.r = 1.0 - exp(1.0 - col.r) / e; - col.g = 1.0 - exp(1.0 - col.g) / e; - col.b = 1.0 - exp(1.0 - col.b) / e; - col = sqrt(col); // Linear -> SRGB - if(fogDistance != 0.0){ - float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); - col = mix(col, skyBgColor, d); - } - gl_FragColor = vec4(col.r, col.g, col.b, alpha); -} +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D useNormalmap; + +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; + +bool normalTexturePresent = false; + +const float e = 2.718281828459; + +float intensity (vec3 color){ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height (vec2 uv){ + return intensity(texture2D(baseTexture,uv).rgb); +} + +vec4 get_normal_map(vec2 uv){ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 -1.0); + bump.y = -bump.y; + return bump; +} + +void main (void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + +#ifdef USE_NORMALMAPS + if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#ifdef GENERATE_NORMALMAPS + if (use_normalmap == false){ + float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y)); + float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP)); + float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0); + use_normalmap = true; + } +#endif + +vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap){ + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5); + float diffuse = dot(E,bump.xyz); + color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + vec4 col = vec4(color.rgb, base.a); + col = col * col; // SRGB -> Linear + col *= 1.8; + col.r = 1.0 - exp(1.0 - col.r) / e; + col.g = 1.0 - exp(1.0 - col.g) / e; + col.b = 1.0 - exp(1.0 - col.b) / e; + col = sqrt(col); // Linear -> SRGB + col *= gl_Color; + if(fogDistance != 0.0){ + float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); + col = mix(col, skyBgColor, d); + } + gl_FragColor = vec4(col.rgb, base.a); +} diff --git a/client/shaders/plants_shader/opengl_vertex.glsl b/client/shaders/plants_shader/opengl_vertex.glsl index 7987fc16..a95c2024 100644 --- a/client/shaders/plants_shader/opengl_vertex.glsl +++ b/client/shaders/plants_shader/opengl_vertex.glsl @@ -1,13 +1,20 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform mat4 mWorld; + uniform float dayNightRatio; uniform float animationTimer; uniform vec3 eyePosition; varying vec3 vPosition; +varying vec3 worldPosition; + varying vec3 eyeVec; +varying vec3 lightVec; + +const float BS = 10.0; #ifdef ENABLE_WAVING_PLANTS float smoothCurve( float x ) { @@ -23,12 +30,11 @@ float smoothTriangleWave( float x ) { void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; #ifdef ENABLE_WAVING_PLANTS vec4 pos = gl_Vertex; - vec4 pos2 = mTransWorld * gl_Vertex; + vec4 pos2 = mWorld * gl_Vertex; if (gl_TexCoord[0].y < 0.05) { pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8; pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4; @@ -38,9 +44,13 @@ void main(void) gl_Position = mWorldViewProj * gl_Vertex; #endif - vPosition = (mWorldViewProj * gl_Vertex).xyz; - eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + vPosition = gl_Position.xyz; + worldPosition = (mWorld * gl_Vertex).xyz; + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); + lightVec = sunPosition - worldPosition; + eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + vec4 color; //color = vec4(1.0, 1.0, 1.0, 1.0); @@ -76,11 +86,8 @@ void main(void) color = color * color; // SRGB -> Linear if(gl_Normal.y <= 0.5) color *= 0.6; - //color *= 0.7; color = sqrt(color); // Linear -> SRGB - color.a = gl_Color.a; gl_FrontColor = gl_BackColor = color; - } diff --git a/client/shaders/solids_shader/opengl_fragment.glsl b/client/shaders/solids_shader/opengl_fragment.glsl index d81506a4..6370bf50 100644 --- a/client/shaders/solids_shader/opengl_fragment.glsl +++ b/client/shaders/solids_shader/opengl_fragment.glsl @@ -1,90 +1,110 @@ -uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D useNormalmap; - -uniform vec4 skyBgColor; -uniform float fogDistance; -uniform vec3 eyePosition; - -varying vec3 vPosition; -varying vec3 eyeVec; - -#ifdef ENABLE_PARALLAX_OCCLUSION -varying vec3 tsEyeVec; -#endif - -const float e = 2.718281828459; - -void main (void) -{ - vec3 color; - vec2 uv = gl_TexCoord[0].st; - -#ifdef USE_NORMALMAPS - float use_normalmap = texture2D(useNormalmap,vec2(1.0,1.0)).r; -#endif - -#ifdef ENABLE_PARALLAX_OCCLUSION - float height; - vec2 tsEye = vec2(tsEyeVec.x,-tsEyeVec.y); - - if (use_normalmap > 0.0) { - float map_height = texture2D(normalTexture, uv).a; - if (map_height < 1.0){ - float height = PARALLAX_OCCLUSION_SCALE * map_height - PARALLAX_OCCLUSION_BIAS; - uv = uv + height * tsEye; - } - } -#endif - -/* Steep parallax code, for future use - if ((parallaxMappingMode == 2.0) && (use_normalmap > 0.0)) { - const float numSteps = 40.0; - float height = 1.0; - float step = 1.0 / numSteps; - vec4 NB = texture2D(normalTexture, uv); - vec2 delta = tsEye * parallaxMappingScale / numSteps; - for (float i = 0.0; i < numSteps; i++) { - if (NB.a < height) { - height -= step; - uv += delta; - NB = texture2D(normalTexture, uv); - } else { - break; - } - } - } -*/ - -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap > 0.0) { - vec3 base = texture2D(baseTexture, uv).rgb; - vec3 vVec = normalize(eyeVec); - vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0); - vec3 R = reflect(-vVec, bump); - vec3 lVec = normalize(vVec); - float diffuse = max(dot(lVec, bump), 0.0); - float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0); - color = mix (base,diffuse*base,1.0) + 0.1 * specular * diffuse; - } else { - color = texture2D(baseTexture, uv).rgb; - } -#else - color = texture2D(baseTexture, uv).rgb; -#endif - - float alpha = texture2D(baseTexture, uv).a; - vec4 col = vec4(color.r, color.g, color.b, alpha); - col *= gl_Color; - col = col * col; // SRGB -> Linear - col *= 1.8; - col.r = 1.0 - exp(1.0 - col.r) / e; - col.g = 1.0 - exp(1.0 - col.g) / e; - col.b = 1.0 - exp(1.0 - col.b) / e; - col = sqrt(col); // Linear -> SRGB - if(fogDistance != 0.0){ - float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); - col = mix(col, skyBgColor, d); - } - gl_FragColor = vec4(col.r, col.g, col.b, alpha); -} +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D useNormalmap; + +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 tsEyeVec; +varying vec3 lightVec; +varying vec3 tsLightVec; + +bool normalTexturePresent = false; + +const float e = 2.718281828459; + +float intensity (vec3 color){ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height (vec2 uv){ + return intensity(texture2D(baseTexture,uv).rgb); +} + +vec4 get_normal_map(vec2 uv){ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 -1.0); + bump.y = -bump.y; + return bump; +} + +void main (void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + +#ifdef USE_NORMALMAPS + if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){ + normalTexturePresent = true; + } +#endif + +#ifdef ENABLE_PARALLAX_OCCLUSION + if (normalTexturePresent){ + vec3 tsEye = normalize(tsEyeVec); + float height = PARALLAX_OCCLUSION_SCALE * texture2D(normalTexture, uv).a - PARALLAX_OCCLUSION_BIAS; + uv = uv + texture2D(normalTexture, uv).z * height * vec2(tsEye.x,-tsEye.y); + } +#endif + +#ifdef USE_NORMALMAPS + if (normalTexturePresent){ + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#ifdef GENERATE_NORMALMAPS + if (use_normalmap == false){ + float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP)); + float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y)); + float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP)); + float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP)); + float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0); + use_normalmap = true; + } +#endif + +vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap){ + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5); + float diffuse = dot(E,bump.xyz); + color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + vec4 col = vec4(color.rgb, base.a); + col = col * col; // SRGB -> Linear + col *= 1.8; + col.r = 1.0 - exp(1.0 - col.r) / e; + col.g = 1.0 - exp(1.0 - col.g) / e; + col.b = 1.0 - exp(1.0 - col.b) / e; + col = sqrt(col); // Linear -> SRGB + col *= gl_Color; + if(fogDistance != 0.0){ + float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); + col = mix(col, skyBgColor, d); + } + gl_FragColor = vec4(col.rgb, base.a); +} diff --git a/client/shaders/solids_shader/opengl_vertex.glsl b/client/shaders/solids_shader/opengl_vertex.glsl index e359955d..356ba2eb 100644 --- a/client/shaders/solids_shader/opengl_vertex.glsl +++ b/client/shaders/solids_shader/opengl_vertex.glsl @@ -1,27 +1,33 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform mat4 mWorld; + uniform float dayNightRatio; uniform vec3 eyePosition; varying vec3 vPosition; -varying vec3 eyeVec; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; -#ifdef ENABLE_PARALLAX_OCCLUSION varying vec3 tsEyeVec; -#endif +varying vec3 tsLightVec; + +const float BS = 10.0; void main(void) { + gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = mWorldViewProj * gl_Vertex; - vPosition = (mWorldViewProj * gl_Vertex).xyz; - eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + vPosition = gl_Position.xyz; + worldPosition = (mWorld * gl_Vertex).xyz; + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); -#ifdef ENABLE_PARALLAX_OCCLUSION - vec3 normal,tangent,binormal; + vec3 normal, tangent, binormal; normal = normalize(gl_NormalMatrix * gl_Normal); - if (gl_Normal.x > 0.5) { // 1.0, 0.0, 0.0 tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0)); @@ -47,25 +53,20 @@ void main(void) tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0)); binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0)); } - mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x, tangent.y, binormal.y, normal.y, tangent.z, binormal.z, normal.z); - tsEyeVec = normalize(eyeVec * tbnMatrix); -#endif + lightVec = sunPosition - worldPosition; + tsLightVec = lightVec * tbnMatrix; + eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz; + tsEyeVec = eyeVec * tbnMatrix; vec4 color; - //color = vec4(1.0, 1.0, 1.0, 1.0); - float day = gl_Color.r; float night = gl_Color.g; float light_source = gl_Color.b; - /*color.r = mix(night, day, dayNightRatio); - color.g = color.r; - color.b = color.r;*/ - float rg = mix(night, day, dayNightRatio); rg += light_source * 2.5; // Make light sources brighter float b = rg; @@ -90,13 +91,8 @@ void main(void) color = color * color; // SRGB -> Linear if(gl_Normal.y <= 0.5) color *= 0.6; - //color *= 0.7; color = sqrt(color); // Linear -> SRGB - color.a = gl_Color.a; gl_FrontColor = gl_BackColor = color; - - gl_TexCoord[0] = gl_MultiTexCoord0; - } diff --git a/minetest.conf.example b/minetest.conf.example index 71a945b5..f728d6c8 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -173,6 +173,14 @@ # Set to true to enable textures bumpmapping. Requires shaders enabled. #enable_bumpmapping = false # Set to true enables parallax occlusion mapping. Requires shaders enabled. +#generate_normalmaps = false +# Set to true enables on the fly normalmap generation (Emboss effect). +# Requires bumpmapping enabled. +#normalmaps_strength = 0.6 +# Strength of generated normalmaps +#normalmaps_smooth = 1 +# Defines sampling step of texture (0 - 2) +# Higher the value normal maps will be smoother #enable_parallax_occlusion = false # Scale of parallax occlusion effect #parallax_occlusion_scale = 0.08 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 6b291bd2..b08d79ae 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -130,8 +130,11 @@ void set_default_settings(Settings *settings) settings->setDefault("preload_item_visuals", "true"); settings->setDefault("enable_bumpmapping", "false"); settings->setDefault("enable_parallax_occlusion", "false"); - settings->setDefault("parallax_occlusion_scale", "0.08"); - settings->setDefault("parallax_occlusion_bias", "0.04"); + settings->setDefault("generate_normalmaps", "false"); + settings->setDefault("normalmaps_strength", "0.6"); + settings->setDefault("normalmaps_smooth", "1"); + settings->setDefault("parallax_occlusion_scale", "0.06"); + settings->setDefault("parallax_occlusion_bias", "0.03"); settings->setDefault("enable_waving_water", "false"); settings->setDefault("water_wave_height", "1.0"); settings->setDefault("water_wave_length", "20.0"); diff --git a/src/game.cpp b/src/game.cpp index 0a9dcfda..761f65f8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -858,14 +858,17 @@ public: services->setPixelShaderConstant("eyePosition", (irr::f32*)&eye_position, 3); services->setVertexShaderConstant("eyePosition", (irr::f32*)&eye_position, 3); - // Normal map texture layer + // Uniform sampler layers + int layer0 = 0; int layer1 = 1; int layer2 = 2; // before 1.8 there isn't a "integer interface", only float #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) + services->setPixelShaderConstant("baseTexture" , (irr::f32*)&layer0, 1); services->setPixelShaderConstant("normalTexture" , (irr::f32*)&layer1, 1); services->setPixelShaderConstant("useNormalmap" , (irr::f32*)&layer2, 1); #else + services->setPixelShaderConstant("baseTexture" , (irr::s32*)&layer0, 1); services->setPixelShaderConstant("normalTexture" , (irr::s32*)&layer1, 1); services->setPixelShaderConstant("useNormalmap" , (irr::s32*)&layer2, 1); #endif diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index ef05acbb..9cd99fcb 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -1212,20 +1212,25 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): ITextureSource *tsrc = data->m_gamedef->tsrc(); material.setTexture(2, tsrc->getTexture("disable_img.png")); if (enable_bumpmapping || enable_parallax_occlusion) { - std::string fname_base = tsrc->getTextureName(p.tile.texture_id); - std::string normal_ext = "_normal.png"; - size_t pos = fname_base.find("."); - std::string fname_normal = fname_base.substr(0, pos) + normal_ext; - - if (tsrc->isKnownSourceImage(fname_normal)) { - // look for image extension and replace it - size_t i = 0; - while ((i = fname_base.find(".", i)) != std::string::npos) { - fname_base.replace(i, 4, normal_ext); - i += normal_ext.length(); - } - material.setTexture(1, tsrc->getTexture(fname_base)); + if (tsrc->isKnownSourceImage("override_normal.png")){ + material.setTexture(1, tsrc->getTexture("override_normal.png")); material.setTexture(2, tsrc->getTexture("enable_img.png")); + } else { + std::string fname_base = tsrc->getTextureName(p.tile.texture_id); + std::string normal_ext = "_normal.png"; + size_t pos = fname_base.find("."); + std::string fname_normal = fname_base.substr(0, pos) + normal_ext; + + if (tsrc->isKnownSourceImage(fname_normal)) { + // look for image extension and replace it + size_t i = 0; + while ((i = fname_base.find(".", i)) != std::string::npos) { + fname_base.replace(i, 4, normal_ext); + i += normal_ext.length(); + } + material.setTexture(1, tsrc->getTexture(fname_base)); + material.setTexture(2, tsrc->getTexture("enable_img.png")); + } } } p.tile.applyMaterialOptionsWithShaders(material, @@ -1368,17 +1373,22 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png")); if (enable_shaders && (enable_bumpmapping || enable_parallax_occlusion)) { - std::string fname_base,fname_normal; - fname_base = tsrc->getTextureName(tile.texture_id); - unsigned pos; - pos = fname_base.find("."); - fname_normal = fname_base.substr (0, pos); - fname_normal += "_normal.png"; - if (tsrc->isKnownSourceImage(fname_normal)){ - os.str(""); - os<getMaterial().setTexture(1, tsrc->getTexture(os.str())); + if (tsrc->isKnownSourceImage("override_normal.png")){ + buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png")); buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png")); + } else { + std::string fname_base,fname_normal; + fname_base = tsrc->getTextureName(tile.texture_id); + unsigned pos; + pos = fname_base.find("."); + fname_normal = fname_base.substr (0, pos); + fname_normal += "_normal.png"; + if (tsrc->isKnownSourceImage(fname_normal)){ + os.str(""); + os<getMaterial().setTexture(1, tsrc->getTexture(os.str())); + buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png")); + } } } } diff --git a/src/shader.cpp b/src/shader.cpp index d29c9d3a..4006e256 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -240,12 +240,20 @@ public: services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4); // set transposed world matrix - core::matrix4 world = driver->getTransform(video::ETS_WORLD); - world = world.getTransposed(); + core::matrix4 transWorld = driver->getTransform(video::ETS_WORLD); + transWorld = transWorld.getTransposed(); if(is_highlevel) - services->setVertexShaderConstant("mTransWorld", world.pointer(), 16); + services->setVertexShaderConstant("mTransWorld", transWorld.pointer(), 16); + else + services->setVertexShaderConstant(transWorld.pointer(), 8, 4); + + // set world matrix + core::matrix4 world = driver->getTransform(video::ETS_WORLD); + if(is_highlevel) + services->setVertexShaderConstant("mWorld", world.pointer(), 16); else services->setVertexShaderConstant(world.pointer(), 8, 4); + } private: @@ -673,7 +681,33 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device, // Create shaders header std::string shaders_header = "#version 120\n"; - + + if (g_settings->getBool("generate_normalmaps")){ + shaders_header += "#define GENERATE_NORMALMAPS\n"; + shaders_header += "#define NORMALMAPS_STRENGTH "; + shaders_header += ftos(g_settings->getFloat("normalmaps_strength")); + shaders_header += "\n"; + float sample_step; + int smooth = (int)g_settings->getFloat("normalmaps_smooth"); + switch (smooth){ + case 0: + sample_step = 0.0078125; // 1.0 / 128.0 + break; + case 1: + sample_step = 0.00390625; // 1.0 / 256.0 + break; + case 2: + sample_step = 0.001953125; // 1.0 / 512.0 + break; + default: + sample_step = 0.0078125; + break; + } + shaders_header += "#define SAMPLE_STEP "; + shaders_header += ftos(sample_step); + shaders_header += "\n"; + } + if (g_settings->getBool("enable_bumpmapping")) shaders_header += "#define ENABLE_BUMPMAPPING\n"; @@ -685,7 +719,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device, shaders_header += "#define PARALLAX_OCCLUSION_BIAS "; shaders_header += ftos(g_settings->getFloat("parallax_occlusion_bias")); shaders_header += "\n"; - } + } if (g_settings->getBool("enable_bumpmapping") || g_settings->getBool("enable_parallax_occlusion")) shaders_header += "#define USE_NORMALMAPS\n"; From 5fefc4bbf6380960f11f0b125fc51b6efdc19e2e Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Fri, 21 Mar 2014 05:18:35 -0400 Subject: [PATCH 23/53] Fix serializing of signed numbers in serializeStructToString --- src/util/serialize.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index f05cfcc9..8779ee63 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -385,6 +385,9 @@ fail: } +// Casts *buf to a signed or unsigned fixed-width integer of 'w' width +#define SIGN_CAST(w, buf) (is_unsigned ? *((u##w *) buf) : *((s##w *) buf)) + bool serializeStructToString(std::string *out, std::string format, void *value) { @@ -412,15 +415,15 @@ bool serializeStructToString(std::string *out, case 'i': if (width == 16) { bufpos += PADDING(bufpos, u16); - os << *((u16 *) bufpos); + os << SIGN_CAST(16, bufpos); bufpos += sizeof(u16); } else if (width == 32) { bufpos += PADDING(bufpos, u32); - os << *((u32 *) bufpos); + os << SIGN_CAST(32, bufpos); bufpos += sizeof(u32); } else if (width == 64) { bufpos += PADDING(bufpos, u64); - os << *((u64 *) bufpos); + os << SIGN_CAST(64, bufpos); bufpos += sizeof(u64); } break; @@ -474,3 +477,5 @@ bool serializeStructToString(std::string *out, return true; } + +#undef SIGN_CAST From 936c6f577ad70c9a467eaed58233e737671375df Mon Sep 17 00:00:00 2001 From: Novatux Date: Tue, 18 Mar 2014 20:02:18 +0100 Subject: [PATCH 24/53] Fix "ghost stacks" created when a player clicks an item on the ground: since the object is not immediately removed, any other code may still think an object is there, therefore leading to item duplication. This code therefore sets the itemstring to '' after the object is picked up to avoid such issues --- builtin/item_entity.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin/item_entity.lua b/builtin/item_entity.lua index 95affe3d..0dcc2dc2 100644 --- a/builtin/item_entity.lua +++ b/builtin/item_entity.lua @@ -116,6 +116,7 @@ minetest.register_entity("__builtin:item", { return end end + self.itemstring = '' self.object:remove() end, }) From 5bd9c236d563f3c5a6e268abb13f291a915cde1c Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 23 Mar 2014 19:15:38 +0100 Subject: [PATCH 25/53] Fix double sending of chat messages --- src/guiFormSpecMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 4751978d..3f9d7f78 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -2702,7 +2702,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) (s.fid == event.GUIEvent.Caller->getID())) { s.send = true; - acceptInput(); if(s.is_exit){ if (m_allowclose) { acceptInput(quit_mode_accept); @@ -2712,6 +2711,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } return true; }else{ + acceptInput(); s.send = false; return true; } From 564e11fc2f3731383cecedac8aade4dd9ecdc243 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Fri, 21 Mar 2014 20:12:13 +0000 Subject: [PATCH 26/53] Fix merge mistake when rebasing for PR #1169 --- src/environment.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 4b842577..630f8d21 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -795,8 +795,7 @@ neighbor_found: // Call all the trigger variations i->abm->trigger(m_env, p, n); i->abm->trigger(m_env, p, n, - active_object_count, - active_object_count_wider + active_object_count); + active_object_count, active_object_count_wider); // Count surrounding objects again if the abms added any if(m_env->m_added_objects > 0) { From 65d1cb8321d4a0519ded130c69ca16a1b9d8a3cc Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Wed, 26 Mar 2014 18:53:11 +0200 Subject: [PATCH 27/53] Fix bug in RemoteClient::GetNextBlocks --- src/clientiface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 06d87d2a..5394cd00 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -140,7 +140,8 @@ void RemoteClient::GetNextBlocks( */ s32 new_nearest_unsent_d = -1; - s16 d_max = g_settings->getS16("max_block_send_distance"); + const s16 full_d_max = g_settings->getS16("max_block_send_distance"); + s16 d_max = full_d_max; s16 d_max_gen = g_settings->getS16("max_block_generate_distance"); // Don't loop very much at a time @@ -214,7 +215,7 @@ void RemoteClient::GetNextBlocks( generate = false;*/ // Limit the send area vertically to 1/2 - if(abs(p.Y - center.Y) > d_max / 2) + if(abs(p.Y - center.Y) > full_d_max / 2) continue; } From af01a9577e488d17e4f2f9145db723f3902446c9 Mon Sep 17 00:00:00 2001 From: sapier Date: Mon, 31 Mar 2014 22:50:03 +0200 Subject: [PATCH 28/53] Fix lost change password button --- src/game.cpp | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 761f65f8..a13f1393 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -154,6 +154,11 @@ struct LocalFormspecHandler : public TextDest return; } + if (fields.find("btn_change_password") != fields.end()) { + g_gamecallback->changePassword(); + return; + } + if (fields.find("quit") != fields.end()) { return; } @@ -1000,7 +1005,7 @@ static void show_chat_menu(FormspecFormSource* current_formspec, /******************************************************************************/ static void show_pause_menu(FormspecFormSource* current_formspec, TextDest* current_textdest, IWritableTextureSource* tsrc, - IrrlichtDevice * device) + IrrlichtDevice * device, bool singleplayermode) { std::string control_text = wide_to_narrow(wstrgettext("Default Controls:\n" @@ -1016,25 +1021,34 @@ static void show_pause_menu(FormspecFormSource* current_formspec, "- T: chat\n" )); + float ypos = singleplayermode ? 1.0 : 0.5; std::ostringstream os; - os<<"Minetest\n"; - os<wasKeyDown(EscapeKey)) { - show_pause_menu(current_formspec, current_textdest, tsrc, device); + show_pause_menu(current_formspec, current_textdest, tsrc, device, + simple_singleplayer_mode); } else if(input->wasKeyDown(getKeySetting("keymap_chat"))) { From 28854495b172cdea6c835bb6482200c4e277b040 Mon Sep 17 00:00:00 2001 From: sapier Date: Thu, 3 Apr 2014 20:26:26 +0200 Subject: [PATCH 29/53] Performance optimized button to button mask evaluation --- src/game.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index a13f1393..699314d3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2307,18 +2307,17 @@ void the_game(bool &kill, bool random_input, InputHandler *input, camera_yaw ); client.setPlayerControl(control); - u32 keyPressed= - 1*(int)input->isKeyDown(getKeySetting("keymap_forward"))+ - 2*(int)input->isKeyDown(getKeySetting("keymap_backward"))+ - 4*(int)input->isKeyDown(getKeySetting("keymap_left"))+ - 8*(int)input->isKeyDown(getKeySetting("keymap_right"))+ - 16*(int)input->isKeyDown(getKeySetting("keymap_jump"))+ - 32*(int)input->isKeyDown(getKeySetting("keymap_special1"))+ - 64*(int)input->isKeyDown(getKeySetting("keymap_sneak"))+ - 128*(int)input->getLeftState()+ - 256*(int)input->getRightState(); LocalPlayer* player = client.getEnv().getLocalPlayer(); - player->keyPressed=keyPressed; + player->keyPressed= + (((int)input->isKeyDown(getKeySetting("keymap_forward")) & 0x1) << 0) | + (((int)input->isKeyDown(getKeySetting("keymap_backward")) & 0x1) << 1) | + (((int)input->isKeyDown(getKeySetting("keymap_left")) & 0x1) << 2) | + (((int)input->isKeyDown(getKeySetting("keymap_right")) & 0x1) << 3) | + (((int)input->isKeyDown(getKeySetting("keymap_jump")) & 0x1) << 4) | + (((int)input->isKeyDown(getKeySetting("keymap_special1")) & 0x1) << 5) | + (((int)input->isKeyDown(getKeySetting("keymap_sneak")) & 0x1) << 6) | + (((int)input->getLeftState() & 0x1) << 7) | + (((int)input->getRightState() & 0x1) << 8); } /* From 556bdc260a6938ddab8db22e2ebc4033ec3757eb Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 6 Apr 2014 10:32:57 +0200 Subject: [PATCH 30/53] Pass pointer to nodedef directly to avoid recalculation in quite often called function --- src/content_mapblock.cpp | 24 ++++++++++++------------ src/mapblock_mesh.cpp | 21 +++++++++------------ src/mapblock_mesh.h | 4 ++-- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index cda1846a..3637094f 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -219,7 +219,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, if(ntop.getContent() == c_flowing || ntop.getContent() == c_source) top_is_same_liquid = true; - u16 l = getInteriorLight(n, 0, data); + u16 l = getInteriorLight(n, 0, nodedef); video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source)); /* @@ -389,10 +389,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, } // Use the light of the node on top if possible else if(nodedef->get(ntop).param_type == CPT_LIGHT) - l = getInteriorLight(ntop, 0, data); + l = getInteriorLight(ntop, 0, nodedef); // Otherwise use the light of this node (the liquid) else - l = getInteriorLight(n, 0, data); + l = getInteriorLight(n, 0, nodedef); video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source)); u8 range = rangelim(nodedef->get(c_flowing).liquid_range, 1, 8); @@ -696,7 +696,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data); - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); for(u32 j=0; j<6; j++) @@ -758,7 +758,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, TileSpec tiles[2]; tiles[0] = getNodeTile(n, p, dirs[0], data); tiles[1] = getNodeTile(n, p, dirs[1], data); - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); v3f pos = intToFloat(p, BS); static const float a=BS/2; @@ -876,7 +876,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, TileSpec tile_leaves = getNodeTile(n, p, v3s16(0,0,0), data); - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); v3f pos = intToFloat(p, BS); @@ -909,7 +909,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); float s = BS/2*f.visual_scale; @@ -950,7 +950,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; - u16 l = getInteriorLight(n, 0, data); + u16 l = getInteriorLight(n, 0, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); float d = (float)BS/16; @@ -993,7 +993,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, TileSpec tile = getNodeTileN(n, p, 0, data); tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); float s = BS/2*f.visual_scale; @@ -1045,7 +1045,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, texturestring_rot, &tile_rot.texture_id); - u16 l = getInteriorLight(n, 1, data); + u16 l = getInteriorLight(n, 1, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); const f32 post_rad=(f32)BS/8; @@ -1294,7 +1294,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; - u16 l = getInteriorLight(n, 0, data); + u16 l = getInteriorLight(n, 0, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); float d = (float)BS/64; @@ -1333,7 +1333,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, }; TileSpec tiles[6]; - u16 l = getInteriorLight(n, 0, data); + u16 l = getInteriorLight(n, 0, nodedef); video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source)); v3f pos = intToFloat(p, BS); diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 9cd99fcb..9f8dd221 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -150,9 +150,8 @@ void MeshMakeData::setSmoothLighting(bool smooth_lighting) Single light bank. */ static u8 getInteriorLight(enum LightBank bank, MapNode n, s32 increment, - MeshMakeData *data) + INodeDefManager *ndef) { - INodeDefManager *ndef = data->m_gamedef->ndef(); u8 light = n.getLight(bank, ndef); while(increment > 0) @@ -173,10 +172,10 @@ static u8 getInteriorLight(enum LightBank bank, MapNode n, s32 increment, Calculate non-smooth lighting at interior of node. Both light banks. */ -u16 getInteriorLight(MapNode n, s32 increment, MeshMakeData *data) +u16 getInteriorLight(MapNode n, s32 increment, INodeDefManager *ndef) { - u16 day = getInteriorLight(LIGHTBANK_DAY, n, increment, data); - u16 night = getInteriorLight(LIGHTBANK_NIGHT, n, increment, data); + u16 day = getInteriorLight(LIGHTBANK_DAY, n, increment, ndef); + u16 night = getInteriorLight(LIGHTBANK_NIGHT, n, increment, ndef); return day | (night << 8); } @@ -185,10 +184,8 @@ u16 getInteriorLight(MapNode n, s32 increment, MeshMakeData *data) Single light bank. */ static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2, - v3s16 face_dir, MeshMakeData *data) + v3s16 face_dir, INodeDefManager *ndef) { - INodeDefManager *ndef = data->m_gamedef->ndef(); - u8 light; u8 l1 = n.getLight(bank, ndef); u8 l2 = n2.getLight(bank, ndef); @@ -227,10 +224,10 @@ static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2, Calculate non-smooth lighting at face of node. Both light banks. */ -u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, MeshMakeData *data) +u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef) { - u16 day = getFaceLight(LIGHTBANK_DAY, n, n2, face_dir, data); - u16 night = getFaceLight(LIGHTBANK_NIGHT, n, n2, face_dir, data); + u16 day = getFaceLight(LIGHTBANK_DAY, n, n2, face_dir, ndef); + u16 night = getFaceLight(LIGHTBANK_NIGHT, n, n2, face_dir, ndef); return day | (night << 8); } @@ -812,7 +809,7 @@ static void getTileInfo( if(data->m_smooth_lighting == false) { lights[0] = lights[1] = lights[2] = lights[3] = - getFaceLight(n0, n1, face_dir, data); + getFaceLight(n0, n1, face_dir, ndef); } else { diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 021309d9..7f523173 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -172,8 +172,8 @@ inline video::SColor MapBlock_LightColor(u8 alpha, u16 light, u8 light_source=0) } // Compute light at node -u16 getInteriorLight(MapNode n, s32 increment, MeshMakeData *data); -u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, MeshMakeData *data); +u16 getInteriorLight(MapNode n, s32 increment, INodeDefManager *ndef); +u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef); u16 getSmoothLight(v3s16 p, v3s16 corner, MeshMakeData *data); // Retrieves the TileSpec of a face of a node From 142e2d3b74ad886eed83b0fc9d6cfea100dae10a Mon Sep 17 00:00:00 2001 From: sapier Date: Thu, 13 Feb 2014 20:17:42 +0100 Subject: [PATCH 31/53] Cleanup client init states by bumping protocol version Don't use TOSERVER_RECEIVED_MEDIA but TOSERVER_CLIENT_READY as indicatio for client ready Handle clients with protocol version < 23 (almost) same way as before Make client tell server about it's version Add client state to not send bogus player position updates prior init complete Add access to statistics information (peer connction time,rtt,version) Fix clients standing stalled in world while preloading item visuals (new clients only) Add get_player_information to read client specific information from lua --- doc/lua_api.txt | 23 +++ src/client.cpp | 57 ++++--- src/client.h | 21 ++- src/clientiface.cpp | 46 ++++-- src/clientiface.h | 166 ++++++++++++++++++- src/clientserver.h | 18 ++- src/connection.cpp | 4 +- src/connection.h | 2 +- src/exceptions.h | 5 + src/game.cpp | 4 +- src/hud.cpp | 6 +- src/script/lua_api/l_server.cpp | 132 ++++++++++++++- src/script/lua_api/l_server.h | 3 + src/server.cpp | 277 +++++++++++++++++++++----------- src/server.h | 5 + 15 files changed, 625 insertions(+), 144 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 71380075..bd060f9f 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1200,6 +1200,29 @@ minetest.features minetest.has_feature(arg) -> bool, missing_features ^ arg: string or table in format {foo=true, bar=true} ^ missing_features: {foo=true, bar=true} +minetest.get_player_information(playername) +^ table containing information about player peer: +{ + address = "127.0.0.1", -- ip address of client + ip_version = 4, -- IPv4 / IPv6 + min_rtt = 0.01, -- minimum round trip time + max_rtt = 0.2, -- maximum round trip time + avg_rtt = 0.02, -- average round trip time + min_jitter = 0.01, -- minimum packet time jitter + max_jitter = 0.5, -- maximum packet time jitter + avg_jitter = 0.03, -- average packet time jitter + connection_uptime = 200, -- seconds since client connected + + -- following information is available on debug build only!!! + -- DO NOT USE IN MODS + --ser_vers = 26, -- serialization version used by client + --prot_vers = 23, -- protocol version used by client + --major = 0, -- major version number + --minor = 4, -- minor version number + --patch = 10, -- patch version number + --vers_string = "0.4.9-git", -- full version string + --state = "Active" -- current client state +} Logging: minetest.debug(line) diff --git a/src/client.cpp b/src/client.cpp index 654052ac..5b3ebed6 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serialization.h" #include "util/serialize.h" #include "config.h" +#include "cmake_config_githash.h" #include "util/directiontables.h" #include "util/pointedthing.h" #include "version.h" @@ -252,7 +253,8 @@ Client::Client( m_last_time_of_day_f(-1), m_time_of_day_update_timer(0), m_recommended_send_interval(0.1), - m_removed_sounds_check_timer(0) + m_removed_sounds_check_timer(0), + m_state(LC_Created) { m_packetcounter_timer = 0.0; //m_delete_unused_sectors_timer = 0.0; @@ -325,17 +327,6 @@ void Client::connect(Address address) m_con.Connect(address); } -bool Client::connectedAndInitialized() -{ - if(m_con.Connected() == false) - return false; - - if(m_server_ser_ver == SER_FMT_VER_INVALID) - return false; - - return true; -} - void Client::step(float dtime) { DSTACK(__FUNCTION_NAME); @@ -372,9 +363,6 @@ void Client::step(float dtime) m_packetcounter.clear(); } } - - // Get connection status - bool connected = connectedAndInitialized(); #if 0 { @@ -467,7 +455,7 @@ void Client::step(float dtime) } #endif - if(connected == false) + if(m_state == LC_Created) { float &counter = m_connection_reinit_timer; counter -= dtime; @@ -632,7 +620,7 @@ void Client::step(float dtime) { counter = 0.0; // connectedAndInitialized() is true, peer exists. - float avg_rtt = m_con.GetPeerAvgRTT(PEER_ID_SERVER); + float avg_rtt = getRTT(); infostream<<"Client: avg_rtt="<= m_recommended_send_interval) + if((m_state == LC_Ready) && (counter >= m_recommended_send_interval)) { counter = 0.0; sendPlayerPos(); @@ -1051,6 +1039,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) // Send as reliable m_con.Send(PEER_ID_SERVER, 1, reply, true); + m_state = LC_Init; + return; } @@ -1937,7 +1927,7 @@ void Client::Send(u16 channelnum, SharedBuffer data, bool reliable) void Client::interact(u8 action, const PointedThing& pointed) { - if(connectedAndInitialized() == false){ + if(m_state != LC_Ready){ infostream<<"Client::interact() " "cancelled (not connected)" < data((u8*)s.c_str(), s.size()); + // Send as reliable + Send(0, data, true); +} + void Client::sendPlayerPos() { LocalPlayer *myplayer = m_env.getLocalPlayer(); @@ -2650,16 +2661,14 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font) infostream<<"- Starting mesh update thread"< m_mesh_data; + + // own state + LocalClientState m_state; }; #endif // !CLIENT_HEADER diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 5394cd00..626e5da7 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -17,6 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + #include "clientiface.h" #include "player.h" #include "settings.h" @@ -397,10 +399,11 @@ void RemoteClient::SetBlocksNotSent(std::map &blocks) void RemoteClient::notifyEvent(ClientStateEvent event) { + std::ostringstream myerror; switch (m_state) { case Invalid: - assert("State update for client in invalid state" != 0); + //intentionally do nothing break; case Created: @@ -420,7 +423,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event) /* GotInit2 SetDefinitionsSent SetMediaSent */ default: - assert("Invalid client state transition!" == 0); + myerror << "Created: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); } break; @@ -446,7 +450,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event) /* Init SetDefinitionsSent SetMediaSent */ default: - assert("Invalid client state transition!" == 0); + myerror << "InitSent: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); } break; @@ -467,14 +472,15 @@ void RemoteClient::notifyEvent(ClientStateEvent event) /* Init GotInit2 SetMediaSent */ default: - assert("Invalid client state transition!" == 0); + myerror << "InitDone: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); } break; case DefinitionsSent: switch(event) { - case SetMediaSent: + case SetClientReady: m_state = Active; break; @@ -488,7 +494,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event) /* Init GotInit2 SetDefinitionsSent */ default: - assert("Invalid client state transition!" == 0); + myerror << "DefinitionsSent: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); } break; @@ -505,7 +512,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event) /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */ default: - assert("Invalid client state transition!" == 0); + myerror << "Active: Invalid client state transition! " << event; + throw ClientStateError(myerror.str()); break; } break; @@ -516,6 +524,11 @@ void RemoteClient::notifyEvent(ClientStateEvent event) } } +u32 RemoteClient::uptime() +{ + return getTime(PRECISION_SECONDS) - m_connection_time; +} + ClientInterface::ClientInterface(con::Connection* con) : m_con(con), @@ -749,7 +762,7 @@ void ClientInterface::event(u16 peer_id, ClientStateEvent event) n->second->notifyEvent(event); } - if ((event == SetMediaSent) || (event == Disconnect) || (event == SetDenied)) + if ((event == SetClientReady) || (event == Disconnect) || (event == SetDenied)) { UpdatePlayerList(); } @@ -763,9 +776,24 @@ u16 ClientInterface::getProtocolVersion(u16 peer_id) std::map::iterator n; n = m_clients.find(peer_id); - // No client to deliver event + // No client to get version if (n == m_clients.end()) return 0; return n->second->net_proto_version; } + +void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full) +{ + JMutexAutoLock conlock(m_clients_mutex); + + // Error check + std::map::iterator n; + n = m_clients.find(peer_id); + + // No client to set versions + if (n == m_clients.end()) + return; + + n->second->setVersionInfo(major,minor,patch,full); +} diff --git a/src/clientiface.h b/src/clientiface.h index a2315b3b..13bb45a8 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -34,6 +34,109 @@ class MapBlock; class ServerEnvironment; class EmergeManager; +/* + * State Transitions + + Start + (peer connect) + | + v + /-----------------\ + | | + | Created | + | | + \-----------------/ + | + | ++-----------------------------+ invalid playername, password +|IN: | or denied by mod +| TOSERVER_INIT |------------------------------ ++-----------------------------+ | + | | + | Auth ok | + | | ++-----------------------------+ | +|OUT: | | +| TOCLIENT_INIT | | ++-----------------------------+ | + | | + v | + /-----------------\ | + | | | + | InitSent | | + | | | + \-----------------/ +------------------ + | | | ++-----------------------------+ +-----------------------------+ | +|IN: | |OUT: | | +| TOSERVER_INIT2 | | TOCLIENT_ACCESS_DENIED | | ++-----------------------------+ +-----------------------------+ | + | | | + v v | + /-----------------\ /-----------------\ | + | | | | | + | InitDone | | Denied | | + | | | | | + \-----------------/ \-----------------/ | + | | ++-----------------------------+ | +|OUT: | | +| TOCLIENT_MOVEMENT | | +| TOCLIENT_ITEMDEF | | +| TOCLIENT_NODEDEF | | +| TOCLIENT_ANNOUNCE_MEDIA | | +| TOCLIENT_DETACHED_INVENTORY | | +| TOCLIENT_TIME_OF_DAY | | ++-----------------------------+ | + | | + | | + | ----------------------------------- | + v | | | + /-----------------\ v | + | | +-----------------------------+ | + | DefinitionsSent | |IN: | | + | | | TOSERVER_REQUEST_MEDIA | | + \-----------------/ | TOSERVER_RECEIVED_MEDIA | | + | +-----------------------------+ | + | ^ | | + | ----------------------------------- | + | | ++-----------------------------+ | +|IN: | | +| TOSERVER_CLIENT_READY | | ++-----------------------------+ | + | async | + v mod action | ++-----------------------------+ (ban,kick) | +|OUT: | | +| TOCLIENT_MOVE_PLAYER | | +| TOCLIENT_PRIVILEGES | | +| TOCLIENT_INVENTORY_FORMSPEC | | +| UpdateCrafting | | +| TOCLIENT_INVENTORY | | +| TOCLIENT_HP (opt) | | +| TOCLIENT_BREATH | | +| TOCLIENT_DEATHSCREEN | | ++-----------------------------+ | + | | + v | + /-----------------\ | + | |------------------------------------------------------ + | Active | + | |---------------------------------- + \-----------------/ timeout | + | +-----------------------------+ + | |OUT: | + | | TOCLIENT_DISCONNECT | + | +-----------------------------+ + | | + | v ++-----------------------------+ /-----------------\ +|IN: | | | +| TOSERVER_DISCONNECT |------------------->| Disconnecting | ++-----------------------------+ | | + \-----------------/ +*/ namespace con { class Connection; } @@ -50,13 +153,24 @@ enum ClientState Active }; +static const char** statenames = (const char*[]) { + "Invalid", + "Disconnecting", + "Denied", + "Created", + "InitSent", + "InitDone", + "DefinitionsSent", + "Active" +}; + enum ClientStateEvent { Init, GotInit2, SetDenied, SetDefinitionsSent, - SetMediaSent, + SetClientReady, Disconnect }; @@ -107,7 +221,12 @@ public: m_excess_gotblocks(0), m_nothing_to_send_counter(0), m_nothing_to_send_pause_timer(0.0), - m_name("") + m_name(""), + m_version_major(0), + m_version_minor(0), + m_version_patch(0), + m_full_version("unknown"), + m_connection_time(getTime(PRECISION_SECONDS)) { } ~RemoteClient() @@ -178,6 +297,23 @@ public: void confirmSerializationVersion() { serialization_version = m_pending_serialization_version; } + /* get uptime */ + u32 uptime(); + + + /* set version information */ + void setVersionInfo(u8 major, u8 minor, u8 patch, std::string full) { + m_version_major = major; + m_version_minor = minor; + m_version_patch = patch; + m_full_version = full; + } + + /* read version information */ + u8 getMajor() { return m_version_major; } + u8 getMinor() { return m_version_minor; } + u8 getPatch() { return m_version_patch; } + std::string getVersion() { return m_full_version; } private: // Version is stored in here after INIT before INIT2 u8 m_pending_serialization_version; @@ -221,7 +357,25 @@ private: // CPU usage optimization u32 m_nothing_to_send_counter; float m_nothing_to_send_pause_timer; + + /* + name of player using this client + */ std::string m_name; + + /* + client information + */ + u8 m_version_major; + u8 m_version_minor; + u8 m_version_patch; + + std::string m_full_version; + + /* + time this client was created + */ + const u32 m_connection_time; }; class ClientInterface { @@ -268,6 +422,9 @@ public: /* get protocol version of client */ u16 getProtocolVersion(u16 peer_id); + /* set client version */ + void setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full); + /* event to update client state */ void event(u16 peer_id, ClientStateEvent event); @@ -275,6 +432,11 @@ public: void setEnv(ServerEnvironment* env) { assert(m_env == 0); m_env = env; } + static std::string state2Name(ClientState state) { + assert(state < sizeof(statenames)); + return statenames[state]; + } + protected: //TODO find way to avoid this functions void Lock() diff --git a/src/clientserver.h b/src/clientserver.h index d1e250ea..5c541863 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -100,9 +100,13 @@ with this program; if not, write to the Free Software Foundation, Inc., version, heat and humidity transfer in MapBock automatic_face_movement_dir and automatic_face_movement_dir_offset added to object properties + PROTOCOL_VERSION 22: + add swap_node + PROTOCOL_VERSION 23: + TOSERVER_CLIENT_READY */ -#define LATEST_PROTOCOL_VERSION 22 +#define LATEST_PROTOCOL_VERSION 23 // Server's supported network protocol range #define SERVER_PROTOCOL_VERSION_MIN 13 @@ -129,7 +133,7 @@ enum ToClientCommand [0] u16 TOSERVER_INIT [2] u8 deployed version - [3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd + [3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd [12] u64 map seed (new as of 2011-02-27) [20] f1000 recommended send interval (in seconds) (new as of 14) @@ -755,6 +759,16 @@ enum ToServerCommand u16 command u16 breath */ + + TOSERVER_CLIENT_READY = 0x43, + /* + u8 major + u8 minor + u8 patch + u8 reserved + u16 len + u8[len] full_version_string + */ }; #endif diff --git a/src/connection.cpp b/src/connection.cpp index 8a23f67c..290e2cb2 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -2875,11 +2875,11 @@ Address Connection::GetPeerAddress(u16 peer_id) return peer_address; } -float Connection::GetPeerAvgRTT(u16 peer_id) +float Connection::getPeerStat(u16 peer_id, rtt_stat_type type) { PeerHelper peer = getPeerNoEx(peer_id); if (!peer) return -1; - return peer->getStat(AVG_RTT); + return peer->getStat(type); } u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd) diff --git a/src/connection.h b/src/connection.h index 9d646f49..0f936eb3 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1004,7 +1004,7 @@ public: void Send(u16 peer_id, u8 channelnum, SharedBuffer data, bool reliable); u16 GetPeerID(){ return m_peer_id; } Address GetPeerAddress(u16 peer_id); - float GetPeerAvgRTT(u16 peer_id); + float getPeerStat(u16 peer_id, rtt_stat_type type); const u32 GetProtocolID() const { return m_protocol_id; }; const std::string getDesc(); void DisconnectPeer(u16 peer_id); diff --git a/src/exceptions.h b/src/exceptions.h index 970c68e4..6d6ad333 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -116,6 +116,11 @@ public: FatalSystemException(const std::string &s): BaseException(s) {} }; +class ClientStateError : public BaseException { +public: + ClientStateError(std::string s): BaseException(s) {} +}; + /* Some "old-style" interrupts: */ diff --git a/src/game.cpp b/src/game.cpp index 699314d3..7d881fa8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1266,7 +1266,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, server->step(dtime); // End condition - if(client.connectedAndInitialized()){ + if(client.getState() == LC_Init){ could_connect = true; break; } @@ -1373,7 +1373,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, errorstream< rect = imgrect + pos + steppos; @@ -334,7 +334,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s steppos = v2s32(0, -1); break; default: - steppos = v2s32(1, 0); + steppos = v2s32(1, 0); } steppos.X *= srcd.Width; steppos.Y *= srcd.Height; @@ -363,7 +363,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s32 breath) { InventoryList *mainlist = inventory->getList("main"); if (mainlist == NULL) { - errorstream << "draw_hotbar(): mainlist == NULL" << std::endl; + //silently ignore this we may not be initialized completely return; } diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index bbf5a707..531d044e 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -99,7 +99,7 @@ int ModApiServer::l_get_player_ip(lua_State *L) } try { - Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id); + Address addr = getServer(L)->getPeerAddress(player->peer_id); std::string ip_str = addr.serializeString(); lua_pushstring(L, ip_str.c_str()); return 1; @@ -112,6 +112,135 @@ int ModApiServer::l_get_player_ip(lua_State *L) } } +// get_player_information() +int ModApiServer::l_get_player_information(lua_State *L) +{ + + NO_MAP_LOCK_REQUIRED; + const char * name = luaL_checkstring(L, 1); + Player *player = getEnv(L)->getPlayer(name); + if(player == NULL) + { + lua_pushnil(L); // no such player + return 1; + } + + Address addr; + try + { + addr = getServer(L)->getPeerAddress(player->peer_id); + } + catch(con::PeerNotFoundException) // unlikely + { + dstream << __FUNCTION_NAME << ": peer was not found" << std::endl; + lua_pushnil(L); // error + return 1; + } + + float min_rtt,max_rtt,avg_rtt,min_jitter,max_jitter,avg_jitter; + ClientState state; + u32 uptime; + u16 prot_vers; + u8 ser_vers,major,minor,patch; + std::string vers_string; + +#define ERET(code) \ + if (!(code)) { \ + dstream << __FUNCTION_NAME << ": peer was not found" << std::endl; \ + lua_pushnil(L); /* error */ \ + return 1; \ + } + + ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_RTT,&min_rtt)) + ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_RTT,&max_rtt)) + ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_RTT,&avg_rtt)) + ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_JITTER,&min_jitter)) + ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_JITTER,&max_jitter)) + ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_JITTER,&avg_jitter)) + + ERET(getServer(L)->getClientInfo(player->peer_id, + &state, &uptime, &ser_vers, &prot_vers, + &major, &minor, &patch, &vers_string)) + + lua_newtable(L); + int table = lua_gettop(L); + + lua_pushstring(L,"address"); + lua_pushstring(L, addr.serializeString().c_str()); + lua_settable(L, table); + + lua_pushstring(L,"ip_version"); + if (addr.getFamily() == AF_INET) { + lua_pushnumber(L, 4); + } else if (addr.getFamily() == AF_INET6) { + lua_pushnumber(L, 6); + } else { + lua_pushnumber(L, 0); + } + lua_settable(L, table); + + lua_pushstring(L,"min_rtt"); + lua_pushnumber(L, min_rtt); + lua_settable(L, table); + + lua_pushstring(L,"max_rtt"); + lua_pushnumber(L, max_rtt); + lua_settable(L, table); + + lua_pushstring(L,"avg_rtt"); + lua_pushnumber(L, avg_rtt); + lua_settable(L, table); + + lua_pushstring(L,"min_jitter"); + lua_pushnumber(L, min_jitter); + lua_settable(L, table); + + lua_pushstring(L,"max_jitter"); + lua_pushnumber(L, max_jitter); + lua_settable(L, table); + + lua_pushstring(L,"avg_jitter"); + lua_pushnumber(L, avg_jitter); + lua_settable(L, table); + + lua_pushstring(L,"connection_uptime"); + lua_pushnumber(L, uptime); + lua_settable(L, table); + +#ifndef NDEBUG + lua_pushstring(L,"serialization_version"); + lua_pushnumber(L, ser_vers); + lua_settable(L, table); + + lua_pushstring(L,"protocol_version"); + lua_pushnumber(L, prot_vers); + lua_settable(L, table); + + lua_pushstring(L,"major"); + lua_pushnumber(L, major); + lua_settable(L, table); + + lua_pushstring(L,"minor"); + lua_pushnumber(L, minor); + lua_settable(L, table); + + lua_pushstring(L,"patch"); + lua_pushnumber(L, patch); + lua_settable(L, table); + + lua_pushstring(L,"version_string"); + lua_pushstring(L, vers_string.c_str()); + lua_settable(L, table); + + lua_pushstring(L,"state"); + lua_pushstring(L,ClientInterface::state2Name(state).c_str()); + lua_settable(L, table); +#endif + +#undef ERET + return 1; +} + // get_ban_list() int ModApiServer::l_get_ban_list(lua_State *L) { @@ -343,6 +472,7 @@ void ModApiServer::Initialize(lua_State *L, int top) API_FCT(sound_play); API_FCT(sound_stop); + API_FCT(get_player_information); API_FCT(get_player_privs); API_FCT(get_player_ip); API_FCT(get_ban_list); diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h index 0d0aa45c..4101f285 100644 --- a/src/script/lua_api/l_server.h +++ b/src/script/lua_api/l_server.h @@ -67,6 +67,9 @@ private: // get_player_ip() static int l_get_player_ip(lua_State *L); + // get_player_information() + static int l_get_player_information(lua_State *L); + // get_ban_list() static int l_get_ban_list(lua_State *L); diff --git a/src/server.cpp b/src/server.cpp index ba7ac1ec..ebb76b08 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1191,6 +1191,111 @@ void Server::Receive() m_env->removePlayer(peer_id);*/ } + catch(ClientStateError &e) + { + errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl; + DenyAccess(peer_id, L"Your client sent something server didn't expect." + L"Try reconnecting or updating your client"); + } +} + +PlayerSAO* Server::StageTwoClientInit(u16 peer_id) +{ + std::string playername = ""; + PlayerSAO *playersao = NULL; + m_clients.Lock(); + RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,InitDone); + if (client != NULL) { + playername = client->getName(); + playersao = emergePlayer(playername.c_str(), peer_id); + } + m_clients.Unlock(); + + RemotePlayer *player = + static_cast(m_env->getPlayer(playername.c_str())); + + // If failed, cancel + if((playersao == NULL) || (player == NULL)) + { + if(player && player->peer_id != 0){ + errorstream<<"Server: "<getBool("enable_damage")) + SendPlayerHP(peer_id); + + // Send Breath + SendPlayerBreath(peer_id); + + // Show death screen if necessary + if(player->hp == 0) + SendDeathscreen(peer_id, false, v3f(0,0,0)); + + // Note things in chat if not in simple singleplayer mode + if(!m_simple_singleplayer_mode) + { + // Send information about server to player in chat + SendChatMessage(peer_id, getStatusString()); + + // Send information about joining in chat + { + std::wstring name = L"unknown"; + Player *player = m_env->getPlayer(peer_id); + if(player != NULL) + name = narrow_to_wide(player->getName()); + + std::wstring message; + message += L"*** "; + message += name; + message += L" joined the game."; + SendChatMessage(PEER_ID_INEXISTENT,message); + } + } + + actionstream<getName() <<" joins game. " << std::endl; + /* + Print out action + */ + { + std::vector names = m_clients.getPlayerNames(); + + actionstream<getName() <<" joins game. List of players: "; + + for (std::vector::iterator i = names.begin(); + i != names.end(); i++) + { + actionstream << *i << " "; + } + + actionstream<getFloat("time_speed"); SendTimeOfDay(peer_id, time, time_speed); + ///// begin compatibility code + if (protocol_version <= 22) { + m_clients.event(peer_id, SetClientReady); + m_script->on_joinplayer(playersao); + } + ///// end compatibility code + // Warnings about protocol version can be issued here if(getClient(peer_id)->net_proto_version < LATEST_PROTOCOL_VERSION) { @@ -1583,6 +1710,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } u8 peer_ser_ver = getClient(peer_id,InitDone)->serialization_version; + u16 peer_proto_ver = getClient(peer_id,InitDone)->net_proto_version; if(peer_ser_ver == SER_FMT_VER_INVALID) { @@ -1615,105 +1743,34 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } else if(command == TOSERVER_RECEIVED_MEDIA) { - std::string playername = ""; - PlayerSAO *playersao = NULL; - m_clients.Lock(); - RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,DefinitionsSent); - if (client != NULL) { - playername = client->getName(); - playersao = emergePlayer(playername.c_str(), peer_id); - } - m_clients.Unlock(); + return; + } + else if(command == TOSERVER_CLIENT_READY) { + // clients <= protocol version 22 did not send ready message, + // they're already initialized + assert(peer_proto_ver > 22); - RemotePlayer *player = - static_cast(m_env->getPlayer(playername.c_str())); + PlayerSAO* playersao = StageTwoClientInit(peer_id); - // If failed, cancel - if((playersao == NULL) || (player == NULL)) - { - if(player && player->peer_id != 0){ - errorstream<<"Server: "<getBool("enable_damage")) - SendPlayerHP(peer_id); - - // Send Breath - SendPlayerBreath(peer_id); - - // Show death screen if necessary - if(player->hp == 0) - SendDeathscreen(peer_id, false, v3f(0,0,0)); - - // Note things in chat if not in simple singleplayer mode - if(!m_simple_singleplayer_mode) - { - // Send information about server to player in chat - SendChatMessage(peer_id, getStatusString()); - - // Send information about joining in chat - { - std::wstring name = L"unknown"; - Player *player = m_env->getPlayer(peer_id); - if(player != NULL) - name = narrow_to_wide(player->getName()); - - std::wstring message; - message += L"*** "; - message += name; - message += L" joined the game."; - SendChatMessage(PEER_ID_INEXISTENT,message); - } - } - - actionstream<getName()<<" ["< names = m_clients.getPlayerNames(); - - actionstream<getName()<<" ["<::iterator i = names.begin(); - i != names.end(); i++) - { - actionstream << *i << " "; - } - - actionstream<on_joinplayer(playersao); - return; + } else if(command == TOSERVER_GOTBLOCKS) { @@ -2809,6 +2866,46 @@ void Server::deletingPeer(con::Peer *peer, bool timeout) m_peer_change_queue.push_back(c); } +bool Server::getClientConInfo(u16 peer_id, con::rtt_stat_type type, float* retval) +{ + *retval = m_con.getPeerStat(peer_id,type); + if (*retval == -1) return false; + return true; +} + +bool Server::getClientInfo( + u16 peer_id, + ClientState* state, + u32* uptime, + u8* ser_vers, + u16* prot_vers, + u8* major, + u8* minor, + u8* patch, + std::string* vers_string + ) +{ + *state = m_clients.getClientState(peer_id); + m_clients.Lock(); + RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,Invalid); + + if (client == NULL) + return false; + + *uptime = client->uptime(); + *ser_vers = client->serialization_version; + *prot_vers = client->net_proto_version; + + *major = client->getMajor(); + *minor = client->getMinor(); + *patch = client->getPatch(); + *vers_string = client->getPatch(); + + m_clients.Unlock(); + + return true; +} + void Server::handlePeerChanges() { while(m_peer_change_queue.size() > 0) diff --git a/src/server.h b/src/server.h index 7813eabb..c0928e57 100644 --- a/src/server.h +++ b/src/server.h @@ -185,6 +185,7 @@ public: // This is run by ServerThread and does the actual processing void AsyncRunStep(bool initial_step=false); void Receive(); + PlayerSAO* StageTwoClientInit(u16 peer_id); void ProcessData(u8 *data, u32 datasize, u16 peer_id); // Environment must be locked when called @@ -331,6 +332,10 @@ public: void deletingPeer(con::Peer *peer, bool timeout); void DenyAccess(u16 peer_id, const std::wstring &reason); + bool getClientConInfo(u16 peer_id, con::rtt_stat_type type,float* retval); + bool getClientInfo(u16 peer_id,ClientState* state, u32* uptime, + u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch, + std::string* vers_string); private: From a88c685f0237b0cb0ed8c5d074a214d52d0924a3 Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 6 Apr 2014 15:20:45 +0200 Subject: [PATCH 32/53] Minor fixes for file/modlist download in mainmenu --- src/script/lua_api/l_mainmenu.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 1a28c9ba..fbb70c38 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -387,11 +387,6 @@ int ModApiMainMenu::l_get_modstore_details(lua_State *L) /******************************************************************************/ int ModApiMainMenu::l_get_modstore_list(lua_State *L) { - std::string listtype = "local"; - - if (!lua_isnone(L,1)) { - listtype = luaL_checkstring(L,1); - } Json::Value mods; std::string url = ""; try{ @@ -990,6 +985,9 @@ int ModApiMainMenu::l_download_file(lua_State *L) lua_pushboolean(L,true); return 1; } + } else { + errorstream << "DOWNLOAD denied: " << absolute_destination + << " isn't a allowed path" << std::endl; } lua_pushboolean(L,false); return 1; From d22621efc10859ae68f51fdcb83da422668dfc91 Mon Sep 17 00:00:00 2001 From: sapier Date: Sun, 6 Apr 2014 10:48:04 +0200 Subject: [PATCH 33/53] Make config honor build system specified config defines --- src/config.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/config.h b/src/config.h index 55bbb5be..1558ebe0 100644 --- a/src/config.h +++ b/src/config.h @@ -9,12 +9,24 @@ #define PROJECT_NAME "Minetest" #define RUN_IN_PLACE 0 #define USE_GETTEXT 0 -#define USE_SOUND 0 -#define USE_CURL 0 +#ifndef USE_SOUND + #define USE_SOUND 0 +#endif + +#ifndef USE_CURL + #define USE_CURL 0 +#endif + #define USE_FREETYPE 0 #define STATIC_SHAREDIR "" -#define USE_LEVELDB 0 -#define USE_LUAJIT 0 + +#ifndef USE_LEVELDB + #define USE_LEVELDB 0 +#endif + +#ifndef USE_LUAJIT + #define USE_LUAJIT 0 +#endif #ifdef USE_CMAKE_CONFIG_H #include "cmake_config.h" From edcad09dee6daf119f3e29b0a63837500e7b8b85 Mon Sep 17 00:00:00 2001 From: sapier Date: Sat, 5 Apr 2014 15:27:33 +0200 Subject: [PATCH 34/53] Add support for named threads (atm linux only) --- src/client.cpp | 4 +++- src/connection.cpp | 4 ++++ src/emerge.cpp | 2 ++ src/httpfetch.cpp | 2 ++ src/porting.h | 20 ++++++++++++++++++++ src/script/lua_api/l_async_events.cpp | 3 +++ src/server.cpp | 2 ++ 7 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/client.cpp b/src/client.cpp index 5b3ebed6..56f55ef6 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -169,6 +169,8 @@ void * MeshUpdateThread::Thread() BEGIN_DEBUG_EXCEPTION_HANDLER + porting::setThreadName("MeshUpdateThread"); + while(!StopRequested()) { QueuedMeshUpdate *q = m_queue_in.pop(); @@ -1212,7 +1214,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) m_time_of_day_set = true; u32 dr = m_env.getDayNightRatio(); - verbosestream<<"Client: time_of_day="<getDesc() << "]"); + porting::setThreadName("ConnectionSend"); + /* if stop is requested don't stop immediately but try to send all */ /* packets first */ while(!StopRequested() || packetsQueued()) { @@ -1955,6 +1957,8 @@ void * ConnectionReceiveThread::Thread() PROFILE(std::stringstream ThreadIdentifier); PROFILE(ThreadIdentifier << "ConnectionReceive: [" << m_connection->getDesc() << "]"); + porting::setThreadName("ConnectionReceive"); + #ifdef DEBUG_CONNECTION_KBPS u32 curtime = porting::getTimeMs(); u32 lasttime = curtime; diff --git a/src/emerge.cpp b/src/emerge.cpp index 0e805c95..c26fab83 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -472,6 +472,8 @@ void *EmergeThread::Thread() { mapgen = emerge->mapgen[id]; enable_mapgen_debug_info = emerge->mapgen_debug_info; + porting::setThreadName("EmergeThread"); + while (!StopRequested()) try { if (!popBlockEmerge(&p, &flags)) { diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index 2eca363d..751a4471 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -566,6 +566,8 @@ protected: log_register_thread("CurlFetchThread"); DSTACK(__FUNCTION_NAME); + porting::setThreadName("CurlFetchThread"); + CurlHandlePool pool; m_multi = curl_multi_init(); diff --git a/src/porting.h b/src/porting.h index c03ae40a..5739b687 100644 --- a/src/porting.h +++ b/src/porting.h @@ -266,6 +266,26 @@ inline u32 getTime(TimePrecision prec) return 0; } +#if (defined(linux) || defined(__linux)) + +#include + +inline void setThreadName(const char* name) { + prctl(PR_SET_NAME,name); +} +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +/* BSD doesn't seem to support thread names. If you know about a way + * to add this feature please create a pull request. + * "setproctitle" doesn't work for threadnames. + */ +#define setThreadName(a) +#elif defined(_WIN32) +// threadnames are not supported on windows +#define setThreadName(a) +#else +#warning "Unknown platform for setThreadName support, you wont have threadname support." +#define setThreadName(a) +#endif } // namespace porting diff --git a/src/script/lua_api/l_async_events.cpp b/src/script/lua_api/l_async_events.cpp index 2425f22b..f5c27a23 100644 --- a/src/script/lua_api/l_async_events.cpp +++ b/src/script/lua_api/l_async_events.cpp @@ -262,6 +262,9 @@ void* AsyncWorkerThread::worker_thread_main() { snprintf(number,sizeof(number),"%d",m_threadnum); log_register_thread(std::string("AsyncWorkerThread_") + number); + porting::setThreadName( + std::string(std::string("AsyncWorkTh_") + number).c_str()); + /** prepare job lua environment **/ lua_newtable(m_LuaStack); lua_setglobal(m_LuaStack, "engine"); diff --git a/src/server.cpp b/src/server.cpp index ebb76b08..0cd8630c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -99,6 +99,8 @@ void * ServerThread::Thread() ThreadStarted(); + porting::setThreadName("ServerThread"); + while(!StopRequested()) { try{ From 6090e95cdcea7c0600ea75941289494505295cf2 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Fri, 7 Mar 2014 01:00:03 +0100 Subject: [PATCH 35/53] Infer ipv6_server from bind_address; fix client connect to IN(6)ADDR_ANY --- minetest.conf.example | 1 + src/game.cpp | 65 ++++++++++++++++++++++++------------------- src/main.cpp | 38 ++++++++++++++----------- src/server.cpp | 5 ++-- src/server.h | 3 +- src/socket.cpp | 21 ++++++++++++++ src/socket.h | 2 ++ 7 files changed, 88 insertions(+), 47 deletions(-) diff --git a/minetest.conf.example b/minetest.conf.example index f728d6c8..4e449533 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -438,6 +438,7 @@ #enable_ipv6 = true # Enable/disable running an IPv6 server. An IPv6 server may be restricted # to IPv6 clients, depending on system configuration. +# Ignored if bind_address is set. #ipv6_server = false #main_menu_script = diff --git a/src/game.cpp b/src/game.cpp index 7d881fa8..f435a4d7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1147,27 +1147,34 @@ void the_game(bool &kill, bool random_input, InputHandler *input, draw_load_screen(text, device, font,0,25); delete[] text; infostream<<"Creating server"<get("bind_address"); Address bind_addr(0,0,0,0, port); - if (bind_str != "") - { - try { - bind_addr.Resolve(bind_str.c_str()); - address = bind_str; - } catch (ResolveError &e) { - infostream << "Resolving bind address \"" << bind_str - << "\" failed: " << e.what() - << " -- Listening on all addresses." << std::endl; - - if (g_settings->getBool("ipv6_server")) { - bind_addr.setAddress((IPv6AddressBytes*) NULL); - } - } + if (g_settings->getBool("ipv6_server")) { + bind_addr.setAddress((IPv6AddressBytes*) NULL); } + try { + bind_addr.Resolve(bind_str.c_str()); + address = bind_str; + } catch (ResolveError &e) { + infostream << "Resolving bind address \"" << bind_str + << "\" failed: " << e.what() + << " -- Listening on all addresses." << std::endl; + } + + if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) { + error_message = L"Unable to listen on " + + narrow_to_wide(bind_addr.serializeString()) + + L" because IPv6 is disabled"; + errorstream<start(bind_addr); } @@ -1193,31 +1200,33 @@ void the_game(bool &kill, bool random_input, InputHandler *input, delete[] text; } Address connect_address(0,0,0,0, port); - try{ - if(address == "") - { + try { + connect_address.Resolve(address.c_str()); + if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY //connect_address.Resolve("localhost"); - if(g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server")) - { + if (connect_address.isIPv6()) { IPv6AddressBytes addr_bytes; addr_bytes.bytes[15] = 1; connect_address.setAddress(&addr_bytes); - } - else - { + } else { connect_address.setAddress(127,0,0,1); } } - else - connect_address.Resolve(address.c_str()); } - catch(ResolveError &e) - { + catch(ResolveError &e) { error_message = L"Couldn't resolve address: " + narrow_to_wide(e.what()); errorstream<getBool("enable_ipv6")) { + error_message = L"Unable to connect to " + + narrow_to_wide(connect_address.serializeString()) + + L" because IPv6 is disabled"; + errorstream<get("bind_address"); - Address bind_addr(0,0,0,0, port); - try { - bind_addr.Resolve(bind_str.c_str()); - } catch (ResolveError &e) { - infostream << "Resolving bind address \"" << bind_str - << "\" failed: " << e.what() - << " -- Listening on all addresses." << std::endl; - - if (g_settings->getBool("ipv6_server")) { - bind_addr.setAddress((IPv6AddressBytes*) NULL); - } - } - // World directory std::string commanded_world = ""; if(cmd_args.exists("world")) @@ -1223,8 +1208,29 @@ int main(int argc, char *argv[]) } verbosestream<<_("Using gameid")<<" ["<get("bind_address"); + Address bind_addr(0,0,0,0, port); + + if (g_settings->getBool("ipv6_server")) { + bind_addr.setAddress((IPv6AddressBytes*) NULL); + } + try { + bind_addr.Resolve(bind_str.c_str()); + } catch (ResolveError &e) { + infostream << "Resolving bind address \"" << bind_str + << "\" failed: " << e.what() + << " -- Listening on all addresses." << std::endl; + } + if(bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) { + errorstream << "Unable to listen on " + << bind_addr.serializeString() + << L" because IPv6 is disabled" << std::endl; + return 1; + } + // Create server - Server server(world_path, gamespec, false); + Server server(world_path, gamespec, false, bind_addr.isIPv6()); // Database migration if (cmd_args.exists("migrate")) { diff --git a/src/server.cpp b/src/server.cpp index 0cd8630c..5c93988b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -166,7 +166,8 @@ v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const Server::Server( const std::string &path_world, const SubgameSpec &gamespec, - bool simple_singleplayer_mode + bool simple_singleplayer_mode, + bool ipv6 ): m_path_world(path_world), m_gamespec(gamespec), @@ -176,7 +177,7 @@ Server::Server( m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, - g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"), + ipv6, this), m_banmanager(NULL), m_rollback(NULL), diff --git a/src/server.h b/src/server.h index c0928e57..ab89fbc6 100644 --- a/src/server.h +++ b/src/server.h @@ -174,7 +174,8 @@ public: Server( const std::string &path_world, const SubgameSpec &gamespec, - bool simple_singleplayer_mode + bool simple_singleplayer_mode, + bool ipv6 ); ~Server(); void start(Address bind_addr); diff --git a/src/socket.cpp b/src/socket.cpp index 00856fb0..bca9c539 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -143,6 +143,15 @@ bool Address::operator!=(Address &address) void Address::Resolve(const char *name) { + if (!name || name[0] == 0) { + if (m_addr_family == AF_INET) { + setAddress((u32) 0); + } else if (m_addr_family == AF_INET6) { + setAddress((IPv6AddressBytes*) 0); + } + return; + } + struct addrinfo *resolved, hints; memset(&hints, 0, sizeof(hints)); @@ -251,6 +260,18 @@ bool Address::isIPv6() const return m_addr_family == AF_INET6; } +bool Address::isZero() const +{ + if (m_addr_family == AF_INET) { + return m_address.ipv4.sin_addr.s_addr == 0; + } else if (m_addr_family == AF_INET6) { + static const char zero[16] = {0}; + return memcmp(m_address.ipv6.sin6_addr.s6_addr, + zero, 16) == 0; + } + return false; +} + void Address::setAddress(u32 address) { m_addr_family = AF_INET; diff --git a/src/socket.h b/src/socket.h index 7d35a32d..92e0cbb1 100644 --- a/src/socket.h +++ b/src/socket.h @@ -88,6 +88,7 @@ public: Address(const IPv6AddressBytes * ipv6_bytes, u16 port); bool operator==(Address &address); bool operator!=(Address &address); + // Resolve() may throw ResolveError (address is unchanged in this case) void Resolve(const char *name); struct sockaddr_in getAddress() const; unsigned short getPort() const; @@ -97,6 +98,7 @@ public: struct sockaddr_in6 getAddress6() const; int getFamily() const; bool isIPv6() const; + bool isZero() const; void setPort(unsigned short port); void print(std::ostream *s) const; std::string serializeString() const; From fefec8cdc44b7fe32754053bac02c18cfe5a22f7 Mon Sep 17 00:00:00 2001 From: BlockMen Date: Fri, 11 Apr 2014 21:38:16 +0200 Subject: [PATCH 36/53] Fix crash when teleporting near unknown node --- builtin/chatcommands.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/builtin/chatcommands.lua b/builtin/chatcommands.lua index 03c278d4..f8df83d8 100644 --- a/builtin/chatcommands.lua +++ b/builtin/chatcommands.lua @@ -261,9 +261,12 @@ minetest.register_chatcommand("teleport", { } for _, d in ipairs(tries) do local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z} - local n = minetest.get_node(p) - if not minetest.registered_nodes[n.name].walkable then - return p, true + local n = minetest.get_node_or_nil(p) + if n and n.name then + local def = minetest.registered_nodes[n.name] + if def and not def.walkable then + return p, true + end end end return pos, false From 8bb8602c2533384fdd5ecb95edc5156808a34db5 Mon Sep 17 00:00:00 2001 From: sapier Date: Fri, 11 Apr 2014 21:45:30 +0200 Subject: [PATCH 37/53] Fix broken win32+bsd build --- src/porting.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/porting.h b/src/porting.h index 5739b687..9024570b 100644 --- a/src/porting.h +++ b/src/porting.h @@ -278,13 +278,13 @@ inline void setThreadName(const char* name) { * to add this feature please create a pull request. * "setproctitle" doesn't work for threadnames. */ -#define setThreadName(a) +inline void setThreadName(const char* name) {} #elif defined(_WIN32) // threadnames are not supported on windows -#define setThreadName(a) +inline void setThreadName(const char* name) {} #else #warning "Unknown platform for setThreadName support, you wont have threadname support." -#define setThreadName(a) +inline void setThreadName(const char* name) {} #endif } // namespace porting From 960d731587f58036bd4957f4a77db41e145c2d04 Mon Sep 17 00:00:00 2001 From: sapier Date: Fri, 11 Apr 2014 22:51:10 +0200 Subject: [PATCH 38/53] Fix broken Ipv4 serialization on win32 --- src/socket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/socket.cpp b/src/socket.cpp index bca9c539..508d61a3 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -202,7 +202,8 @@ std::string Address::serializeString() const #ifdef _WIN32 if(m_addr_family == AF_INET) { - u8 a, b, c, d, addr; + u8 a, b, c, d; + u32 addr; addr = ntohl(m_address.ipv4.sin_addr.s_addr); a = (addr & 0xFF000000) >> 24; b = (addr & 0x00FF0000) >> 16; From 7cdbb805d9f230b2cf00150884dc3fa4fbcde16f Mon Sep 17 00:00:00 2001 From: BlockMen Date: Sat, 12 Apr 2014 17:36:40 +0200 Subject: [PATCH 39/53] Fix MSVC build --- src/clientiface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clientiface.h b/src/clientiface.h index 13bb45a8..95f8bd30 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -153,7 +153,7 @@ enum ClientState Active }; -static const char** statenames = (const char*[]) { +static const char* statenames[] = { "Invalid", "Disconnecting", "Denied", From e149d1ad9a623b9f8ca597839f7b850841c54781 Mon Sep 17 00:00:00 2001 From: BlockMen Date: Sat, 12 Apr 2014 17:39:51 +0200 Subject: [PATCH 40/53] Fix write and read S32 vectors --- src/util/serialize.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/util/serialize.h b/src/util/serialize.h index 63713f7c..3f992528 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -166,14 +166,14 @@ inline v2s16 readV2S16(const u8 *data) inline void writeV2S32(u8 *data, v2s32 p) { writeS32(&data[0], p.X); - writeS32(&data[2], p.Y); + writeS32(&data[4], p.Y); } inline v2s32 readV2S32(const u8 *data) { v2s32 p; p.X = readS32(&data[0]); - p.Y = readS32(&data[2]); + p.Y = readS32(&data[4]); return p; } @@ -346,6 +346,19 @@ inline v2s16 readV2S16(std::istream &is) return readV2S16((u8*)buf); } +inline void writeV2S32(std::ostream &os, v2s32 p) +{ + char buf[8] = {0}; + writeV2S32((u8*)buf, p); + os.write(buf, 8); +} +inline v2s32 readV2S32(std::istream &is) +{ + char buf[8] = {0}; + is.read(buf, 8); + return readV2S32((u8*)buf); +} + inline void writeV3S16(std::ostream &os, v3s16 p) { char buf[6] = {0}; From a1db9242ec491efdee70a7184aa61e861b17595a Mon Sep 17 00:00:00 2001 From: BlockMen Date: Wed, 8 Jan 2014 13:47:53 +0100 Subject: [PATCH 41/53] Add third person view --- doc/lua_api.txt | 6 +++ minetest.conf.example | 1 + src/camera.cpp | 61 ++++++++++++++++++++---- src/camera.h | 5 +- src/client.cpp | 14 ++++++ src/clientmap.cpp | 6 ++- src/clientserver.h | 10 ++++ src/content_cao.cpp | 82 ++++++++++++++++++++++++++++++--- src/defaultsettings.cpp | 1 + src/game.cpp | 30 ++++++++++-- src/game.h | 1 + src/hud.cpp | 4 +- src/localplayer.cpp | 4 +- src/localplayer.h | 5 ++ src/player.h | 3 ++ src/script/lua_api/l_object.cpp | 26 +++++++++++ src/script/lua_api/l_object.h | 3 ++ src/server.cpp | 27 +++++++++++ src/server.h | 3 ++ 19 files changed, 270 insertions(+), 22 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index bd060f9f..bfc12941 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1874,6 +1874,12 @@ Player-only: (no-op for other objects) - override_day_night_ratio(ratio or nil) ^ 0...1: Overrides day-night ratio, controlling sunlight to a specific amount ^ nil: Disables override, defaulting to sunlight based on day-night cycle +- set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, frame_speed=30): set animation for player model in third person view + ^ stand/idle animation key frames + ^ walk animation key frames + ^ dig animation key frames + ^ walk+dig animation key frames + ^ animation frame speed InvRef: Reference to an inventory methods: diff --git a/minetest.conf.example b/minetest.conf.example index 4e449533..6b2867c3 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -361,6 +361,7 @@ # try reducing it, but don't reduce it to a number below double of targeted # client number #max_packets_per_iteration = 1024 + # # Physics stuff # diff --git a/src/camera.cpp b/src/camera.cpp index 783ae84c..6d17ff74 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -40,6 +40,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAMERA_OFFSET_STEP 200 +#include "nodedef.h" +#include "game.h" // CameraModes + Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, IGameDef *gamedef): m_smgr(smgr), @@ -248,7 +251,8 @@ void Camera::step(f32 dtime) } void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, - v2u32 screensize, f32 tool_reload_ratio) + v2u32 screensize, f32 tool_reload_ratio, + int current_camera_mode, ClientEnvironment &c_env) { // Get player position // Smooth the movement when walking up stairs @@ -276,7 +280,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, // Fall bobbing animation float fall_bobbing = 0; - if(player->camera_impact >= 1) + if(player->camera_impact >= 1 && current_camera_mode < CAMERA_MODE_THIRD) { if(m_view_bobbing_fall == -1) // Effect took place and has finished player->camera_impact = m_view_bobbing_fall = 0; @@ -303,7 +307,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, v3f rel_cam_target = v3f(0,0,1); v3f rel_cam_up = v3f(0,1,0); - if (m_view_bobbing_anim != 0) + if (m_view_bobbing_anim != 0 && current_camera_mode < CAMERA_MODE_THIRD) { f32 bobfrac = my_modf(m_view_bobbing_anim * 2); f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0; @@ -352,19 +356,60 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, v3f abs_cam_up; m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up); + // Seperate camera position for calculation + v3f my_cp = m_camera_position; + + // Reposition the camera for third person view + if (current_camera_mode > CAMERA_MODE_FIRST) { + + if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + m_camera_direction *= -1; + + my_cp.Y += 2; + + // Calculate new position + bool abort = false; + for (int i = BS; i <= BS*2; i++) { + my_cp.X = m_camera_position.X + m_camera_direction.X*-i; + my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i; + if (i > 12) + my_cp.Y = m_camera_position.Y + (m_camera_direction.Y*-i); + + // Prevent camera positioned inside nodes + INodeDefManager *nodemgr = m_gamedef->ndef(); + MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS)); + const ContentFeatures& features = nodemgr->get(n); + if(features.walkable) { + my_cp.X += m_camera_direction.X*-1*-BS/2; + my_cp.Z += m_camera_direction.Z*-1*-BS/2; + my_cp.Y += m_camera_direction.Y*-1*-BS/2; + abort = true; + break; + } + } + + // If node blocks camera position don't move y to heigh + if (abort && my_cp.Y > player_position.Y+BS*2) + my_cp.Y = player_position.Y+BS*2; + } + // Update offset if too far away from the center of the map m_camera_offset.X += CAMERA_OFFSET_STEP* - (((s16)(m_camera_position.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP); + (((s16)(my_cp.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP); m_camera_offset.Y += CAMERA_OFFSET_STEP* - (((s16)(m_camera_position.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP); + (((s16)(my_cp.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP); m_camera_offset.Z += CAMERA_OFFSET_STEP* - (((s16)(m_camera_position.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP); + (((s16)(my_cp.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP); // Set camera node transformation - m_cameranode->setPosition(m_camera_position-intToFloat(m_camera_offset, BS)); + m_cameranode->setPosition(my_cp-intToFloat(m_camera_offset, BS)); m_cameranode->setUpVector(abs_cam_up); // *100.0 helps in large map coordinates - m_cameranode->setTarget(m_camera_position-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction); + m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction); + + // update the camera position in front-view mode to render blocks behind player + if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + m_camera_position = my_cp; // Get FOV setting f32 fov_degrees = g_settings->getFloat("fov"); diff --git a/src/camera.h b/src/camera.h index df40e3b9..645b9355 100644 --- a/src/camera.h +++ b/src/camera.h @@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include +#include "client.h" + class LocalPlayer; struct MapDrawControl; class IGameDef; @@ -113,7 +115,8 @@ public: // Update the camera from the local player's position. // busytime is used to adjust the viewing range. void update(LocalPlayer* player, f32 frametime, f32 busytime, - v2u32 screensize, f32 tool_reload_ratio); + v2u32 screensize, f32 tool_reload_ratio, + int current_camera_mode, ClientEnvironment &c_env); // Render distance feedback loop void updateViewingRange(f32 frametime_in, f32 busytime_in); diff --git a/src/client.cpp b/src/client.cpp index 56f55ef6..4f392ad7 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1914,6 +1914,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) event.override_day_night_ratio.ratio_f = day_night_ratio_f; m_client_event_queue.push_back(event); } + else if(command == TOCLIENT_LOCAL_PLAYER_ANIMATIONS) + { + std::string datastring((char *)&data[2], datasize - 2); + std::istringstream is(datastring, std::ios_base::binary); + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + player->local_animations[0] = readV2F1000(is); + player->local_animations[1] = readV2F1000(is); + player->local_animations[2] = readV2F1000(is); + player->local_animations[3] = readV2F1000(is); + player->local_animation_speed = readF1000(is); + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/clientmap.cpp b/src/clientmap.cpp index 20a59f26..c8b2d412 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "profiler.h" #include "settings.h" +#include "game.h" // CameraModes #include "util/mathconstants.h" #include @@ -866,13 +867,16 @@ void ClientMap::renderPostFx() v3f camera_position = m_camera_position; m_camera_mutex.Unlock(); + LocalPlayer *player = m_client->getEnv().getLocalPlayer(); + MapNode n = getNodeNoEx(floatToInt(camera_position, BS)); // - If the player is in a solid node, make everything black. // - If the player is in liquid, draw a semi-transparent overlay. + // - Do not if player is in third person mode const ContentFeatures& features = nodemgr->get(n); video::SColor post_effect_color = features.post_effect_color; - if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip"))) + if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")) && player->camera_mode == CAMERA_MODE_FIRST) { post_effect_color = video::SColor(255, 0, 0, 0); } diff --git a/src/clientserver.h b/src/clientserver.h index 5c541863..3d1adfc2 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -530,6 +530,16 @@ enum ToClientCommand u8 do_override (boolean) u16 day-night ratio 0...65535 */ + + TOCLIENT_LOCAL_PLAYER_ANIMATIONS = 0x51, + /* + u16 command + v2f1000 stand/idle + v2f1000 walk + v2f1000 dig + v2f1000 walk+dig + f1000 frame_speed + */ }; enum ToServerCommand diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 84ec3e14..dc3bae00 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/mathconstants.h" #include "map.h" #include "main.h" // g_settings +#include "game.h" // CameraModes #include #include #include @@ -858,7 +859,7 @@ public: m_visuals_expired = false; - if(!m_prop.is_visible || m_is_local_player) + if(!m_prop.is_visible) return; //video::IVideoDriver* driver = smgr->getVideoDriver(); @@ -1078,6 +1079,60 @@ public: void step(float dtime, ClientEnvironment *env) { + // Handel model of local player instantly to prevent lags + if(m_is_local_player) { + LocalPlayer *player = m_env->getLocalPlayer(); + + if (player->camera_mode > CAMERA_MODE_FIRST) { + int old_anim = player->last_animation; + float old_anim_speed = player->last_animation_speed; + m_is_visible = true; + m_position = player->getPosition() + v3f(0,BS,0); + m_velocity = v3f(0,0,0); + m_acceleration = v3f(0,0,0); + pos_translator.vect_show = m_position; + m_yaw = player->getYaw(); + PlayerControl controls = player->getPlayerControl(); + + bool walking = false; + if(controls.up || controls.down || controls.left || controls.right) + walking = true; + + m_animation_speed = player->local_animation_speed; + if(controls.sneak && walking) + m_animation_speed = player->local_animation_speed/2; + + player->last_animation_speed = m_animation_speed; + + if(walking && (controls.LMB || controls.RMB)) { + m_animation_range = player->local_animations[3]; + player->last_animation = WD_ANIM; + } else if(walking) { + m_animation_range = player->local_animations[1]; + player->last_animation = WALK_ANIM; + } else if(controls.LMB || controls.RMB) { + m_animation_range = player->local_animations[2]; + player->last_animation = DIG_ANIM; + } + + // reset animation when no input detected + if (!walking && !controls.LMB && !controls.RMB) { + player->last_animation = NO_ANIM; + if (old_anim != NO_ANIM) { + m_animation_range = player->local_animations[0]; + updateAnimation(); + } + } + + // Update local player animations + if ((player->last_animation != old_anim && player->last_animation != NO_ANIM) || m_animation_speed != old_anim_speed) + updateAnimation(); + + } else { + m_is_visible = false; + } + } + if(m_visuals_expired && m_smgr && m_irr){ m_visuals_expired = false; @@ -1701,6 +1756,7 @@ public: bool sneak = !readU8(is); bool sneak_glitch = !readU8(is); + if(m_is_local_player) { LocalPlayer *player = m_env->getLocalPlayer(); @@ -1713,11 +1769,25 @@ public: } else if(cmd == GENERIC_CMD_SET_ANIMATION) { - m_animation_range = readV2F1000(is); - m_animation_speed = readF1000(is); - m_animation_blend = readF1000(is); - - updateAnimation(); + if (!m_is_local_player) { + m_animation_range = readV2F1000(is); + m_animation_speed = readF1000(is); + m_animation_blend = readF1000(is); + updateAnimation(); + } else { + LocalPlayer *player = m_env->getLocalPlayer(); + if(player->last_animation == NO_ANIM) { + m_animation_range = readV2F1000(is); + m_animation_speed = readF1000(is); + m_animation_blend = readF1000(is); + } + // update animation only if object is not player + // or the received animation is not registered + if(m_animation_range.X != player->local_animations[1].X && + m_animation_range.X != player->local_animations[2].X && + m_animation_range.X != player->local_animations[3].X) + updateAnimation(); + } } else if(cmd == GENERIC_CMD_SET_BONE_POSITION) { diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index b08d79ae..c39fa54a 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -53,6 +53,7 @@ void set_default_settings(Settings *settings) settings->setDefault("keymap_toggle_update_camera", "KEY_F4"); settings->setDefault("keymap_toggle_debug", "KEY_F5"); settings->setDefault("keymap_toggle_profiler", "KEY_F6"); + settings->setDefault("keymap_camera_mode", "KEY_F7"); settings->setDefault("keymap_increase_viewing_range_min", "+"); settings->setDefault("keymap_decrease_viewing_range_min", "-"); settings->setDefault("anaglyph", "false"); diff --git a/src/game.cpp b/src/game.cpp index f435a4d7..02308b65 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -977,6 +977,8 @@ bool nodePlacementPrediction(Client &client, return false; } +bool is_third_person = false; + static void show_chat_menu(FormspecFormSource* current_formspec, TextDest* current_textdest, IWritableTextureSource* tsrc, IrrlichtDevice * device, Client* client, std::string text) @@ -1470,6 +1472,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input, f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" + int current_camera_mode = CAMERA_MODE_FIRST; // start in first-person view + /* Clouds */ @@ -2251,7 +2255,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, else{ s32 dx = input->getMousePos().X - displaycenter.X; s32 dy = input->getMousePos().Y - displaycenter.Y; - if(invert_mouse) + if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT) dy = -dy; //infostream<<"window active, pos difference "<wasKeyDown(getKeySetting("keymap_camera_mode"))) { + + if (current_camera_mode == CAMERA_MODE_FIRST) + current_camera_mode = CAMERA_MODE_THIRD; + else if (current_camera_mode == CAMERA_MODE_THIRD) + current_camera_mode = CAMERA_MODE_THIRD_FRONT; + else + current_camera_mode = CAMERA_MODE_FIRST; + + } + player->camera_mode = current_camera_mode; tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0); - camera.update(player, dtime, busytime, screensize, - tool_reload_ratio); + camera.update(player, dtime, busytime, screensize, tool_reload_ratio, + current_camera_mode, client.getEnv()); camera.step(dtime); v3f player_position = player->getPosition(); @@ -2717,6 +2733,10 @@ void the_game(bool &kill, bool random_input, InputHandler *input, core::line3d shootline(camera_position, camera_position + camera_direction * BS * (d+1)); + // prevent player pointing anything in front-view + if (current_camera_mode == CAMERA_MODE_THIRD_FRONT) + shootline = core::line3d(0,0,0,0,0,0); + ClientActiveObject *selected_object = NULL; PointedThing pointed = getPointedThing( @@ -3507,7 +3527,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input, /* Wielded tool */ - if(show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE)) + if(show_hud && + (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) && + current_camera_mode < CAMERA_MODE_THIRD) { // Warning: This clears the Z buffer. camera.drawWieldedTool(); diff --git a/src/game.h b/src/game.h index 1c831c53..de0b8483 100644 --- a/src/game.h +++ b/src/game.h @@ -124,6 +124,7 @@ public: class ChatBackend; /* to avoid having to include chat.h */ struct SubgameSpec; +enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; void the_game( bool &kill, diff --git a/src/hud.cpp b/src/hud.cpp index f87fdfc1..d2101117 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include "localplayer.h" #include "camera.h" +#include "game.h" // CameraModes #include @@ -384,7 +385,8 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s void Hud::drawCrosshair() { - if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE)) + if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) || + player->camera_mode == CAMERA_MODE_THIRD_FRONT) return; if (use_crosshair_image) { diff --git a/src/localplayer.cpp b/src/localplayer.cpp index a6f04849..276d8e57 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -50,7 +50,9 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_need_to_get_new_sneak_node(true), - m_can_jump(false) + m_can_jump(false), + camera_mode(0), + last_animation(NO_ANIM) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points diff --git a/src/localplayer.h b/src/localplayer.h index b6a3ed1f..4a35ca92 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -27,6 +27,8 @@ class ClientEnvironment; class ClientActiveObject; +enum localPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both + class LocalPlayer : public Player { public: @@ -60,6 +62,9 @@ public: unsigned int last_keyPressed; float camera_impact; + int camera_mode; + int last_animation; + float last_animation_speed; std::string hotbar_image; std::string hotbar_selected_image; diff --git a/src/player.h b/src/player.h index a1050d4c..b9783997 100644 --- a/src/player.h +++ b/src/player.h @@ -269,6 +269,9 @@ public: bool physics_override_sneak; bool physics_override_sneak_glitch; + v2f local_animations[4]; + float local_animation_speed; + u16 hp; float hurt_tilt_timer; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 90af51cc..e801ddd5 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -406,6 +406,31 @@ int ObjectRef::l_set_animation(lua_State *L) return 0; } +// set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) +int ObjectRef::l_set_local_animation(lua_State *L) +{ + //NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + Player *player = getplayer(ref); + if (player == NULL) + return 0; + // Do it + v2f frames[4]; + for (int i=0;i<4;i++) { + if(!lua_isnil(L, 2+1)) + frames[i] = read_v2f(L, 2+i); + } + float frame_speed = 30; + if(!lua_isnil(L, 6)) + frame_speed = lua_tonumber(L, 6); + + if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed)) + return 0; + + lua_pushboolean(L, true); + return 0; +} + // set_bone_position(self, std::string bone, v3f position, v3f rotation) int ObjectRef::l_set_bone_position(lua_State *L) { @@ -1270,5 +1295,6 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, hud_set_hotbar_selected_image), luamethod(ObjectRef, set_sky), luamethod(ObjectRef, override_day_night_ratio), + luamethod(ObjectRef, set_local_animation), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 2c53d1a6..be1068c1 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -231,6 +231,9 @@ private: // override_day_night_ratio(self, type, list) static int l_override_day_night_ratio(lua_State *L); + // set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) + static int l_set_local_animation(lua_State *L); + public: ObjectRef(ServerActiveObject *object); diff --git a/src/server.cpp b/src/server.cpp index 5c93988b..4f42cfab 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3484,6 +3484,24 @@ void Server::SendMovePlayer(u16 peer_id) m_clients.send(peer_id, 0, data, true); } +void Server::SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed) +{ + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_LOCAL_PLAYER_ANIMATIONS); + writeV2F1000(os, animation_frames[0]); + writeV2F1000(os, animation_frames[1]); + writeV2F1000(os, animation_frames[2]); + writeV2F1000(os, animation_frames[3]); + writeF1000(os, animation_speed); + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8 *)s.c_str(), s.size()); + // Send as reliable + m_clients.send(peer_id, 0, data, true); +} + void Server::SendPlayerPrivileges(u16 peer_id) { Player *player = m_env->getPlayer(peer_id); @@ -4578,6 +4596,15 @@ void Server::hudSetHotbarSelectedImage(Player *player, std::string name) { SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name); } +bool Server::setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed) +{ + if (!player) + return false; + + SendLocalPlayerAnimations(player->peer_id, animation_frames, frame_speed); + return true; +} + bool Server::setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { diff --git a/src/server.h b/src/server.h index ab89fbc6..c796fc82 100644 --- a/src/server.h +++ b/src/server.h @@ -322,6 +322,8 @@ public: inline Address getPeerAddress(u16 peer_id) { return m_con.GetPeerAddress(peer_id); } + bool setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed); + bool setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); @@ -361,6 +363,7 @@ private: void SendPlayerHP(u16 peer_id); void SendPlayerBreath(u16 peer_id); void SendMovePlayer(u16 peer_id); + void SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname); From c0ab09af747fc431dfb459ede30788cb9cd1c56b Mon Sep 17 00:00:00 2001 From: BlockMen Date: Fri, 11 Apr 2014 15:32:46 +0200 Subject: [PATCH 42/53] Add player:set_eye_offset() by @MirceaKitsune and clean up --- doc/lua_api.txt | 3 +++ src/camera.cpp | 10 ++++++++-- src/camera.h | 2 ++ src/client.cpp | 11 +++++++++++ src/clientmap.cpp | 2 +- src/clientserver.h | 7 +++++++ src/content_cao.cpp | 10 ++++++++-- src/game.cpp | 2 -- src/game.h | 1 - src/hud.cpp | 1 - src/localplayer.cpp | 4 +++- src/localplayer.h | 5 ++++- src/script/lua_api/l_object.cpp | 33 ++++++++++++++++++++++++++++++++- src/script/lua_api/l_object.h | 5 ++++- src/server.cpp | 23 +++++++++++++++++++++++ src/server.h | 2 ++ 16 files changed, 108 insertions(+), 13 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index bfc12941..b9865ae4 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1880,6 +1880,9 @@ Player-only: (no-op for other objects) ^ dig animation key frames ^ walk+dig animation key frames ^ animation frame speed +- set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0}): defines offset value for camera per player + ^ in first person view + ^ in third person view (max. values {x=-10/10,y=-10,15,z=-5/5}) InvRef: Reference to an inventory methods: diff --git a/src/camera.cpp b/src/camera.cpp index 6d17ff74..6fbd1dd8 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -41,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAMERA_OFFSET_STEP 200 #include "nodedef.h" -#include "game.h" // CameraModes Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, IGameDef *gamedef): @@ -297,8 +296,15 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, fall_bobbing *= g_settings->getFloat("fall_bobbing_amount"); } + // Calculate players eye offset for different camera modes + v3f PlayerEyeOffset = player->getEyeOffset(); + if (current_camera_mode == CAMERA_MODE_FIRST) + PlayerEyeOffset += player->eye_offset_first; + else + PlayerEyeOffset += player->eye_offset_third; + // Set head node transformation - m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0)); + m_headnode->setPosition(PlayerEyeOffset+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0)); m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength)); m_headnode->updateAbsolutePosition(); diff --git a/src/camera.h b/src/camera.h index 645b9355..82c8d4be 100644 --- a/src/camera.h +++ b/src/camera.h @@ -33,6 +33,8 @@ class LocalPlayer; struct MapDrawControl; class IGameDef; +enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; + /* Client camera class, manages the player and camera scene nodes, the viewing distance and performs view bobbing etc. It also displays the wielded tool in front of the diff --git a/src/client.cpp b/src/client.cpp index 4f392ad7..dbe95906 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1928,6 +1928,17 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) player->local_animations[3] = readV2F1000(is); player->local_animation_speed = readF1000(is); } + else if(command == TOCLIENT_EYE_OFFSET) + { + std::string datastring((char *)&data[2], datasize - 2); + std::istringstream is(datastring, std::ios_base::binary); + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + player->eye_offset_first = readV3F1000(is); + player->eye_offset_third = readV3F1000(is); + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/clientmap.cpp b/src/clientmap.cpp index c8b2d412..0a5d00b9 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "profiler.h" #include "settings.h" -#include "game.h" // CameraModes +#include "camera.h" // CameraModes #include "util/mathconstants.h" #include diff --git a/src/clientserver.h b/src/clientserver.h index 3d1adfc2..a8cd2ea7 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -540,6 +540,13 @@ enum ToClientCommand v2f1000 walk+dig f1000 frame_speed */ + + TOCLIENT_EYE_OFFSET = 0x52, + /* + u16 command + v3f1000 first + v3f1000 third + */ }; enum ToServerCommand diff --git a/src/content_cao.cpp b/src/content_cao.cpp index dc3bae00..dbaf13cc 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -41,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/mathconstants.h" #include "map.h" #include "main.h" // g_settings -#include "game.h" // CameraModes +#include "camera.h" // CameraModes #include #include #include @@ -1099,8 +1099,14 @@ public: walking = true; m_animation_speed = player->local_animation_speed; + if(!player->touching_ground && + g_settings->getBool("free_move") && + m_gamedef->checkLocalPrivilege("fly") && + g_settings->getBool("fast_move") && + m_gamedef->checkLocalPrivilege("fast")) + m_animation_speed *= 1.5; if(controls.sneak && walking) - m_animation_speed = player->local_animation_speed/2; + m_animation_speed /= 2; player->last_animation_speed = m_animation_speed; diff --git a/src/game.cpp b/src/game.cpp index 02308b65..2e8d3761 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -977,8 +977,6 @@ bool nodePlacementPrediction(Client &client, return false; } -bool is_third_person = false; - static void show_chat_menu(FormspecFormSource* current_formspec, TextDest* current_textdest, IWritableTextureSource* tsrc, IrrlichtDevice * device, Client* client, std::string text) diff --git a/src/game.h b/src/game.h index de0b8483..1c831c53 100644 --- a/src/game.h +++ b/src/game.h @@ -124,7 +124,6 @@ public: class ChatBackend; /* to avoid having to include chat.h */ struct SubgameSpec; -enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; void the_game( bool &kill, diff --git a/src/hud.cpp b/src/hud.cpp index d2101117..75075564 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include "localplayer.h" #include "camera.h" -#include "game.h" // CameraModes #include diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 276d8e57..264463d3 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -52,7 +52,9 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): m_need_to_get_new_sneak_node(true), m_can_jump(false), camera_mode(0), - last_animation(NO_ANIM) + last_animation(NO_ANIM), + eye_offset_first(v3f(0,0,0)), + eye_offset_third(v3f(0,0,0)) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points diff --git a/src/localplayer.h b/src/localplayer.h index 4a35ca92..67deb936 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -27,7 +27,7 @@ class ClientEnvironment; class ClientActiveObject; -enum localPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both +enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both class LocalPlayer : public Player { @@ -63,6 +63,9 @@ public: float camera_impact; int camera_mode; + v3f eye_offset_first; + v3f eye_offset_third; + int last_animation; float last_animation_speed; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index e801ddd5..8f2bde03 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -406,7 +406,7 @@ int ObjectRef::l_set_animation(lua_State *L) return 0; } -// set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) +// set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed) int ObjectRef::l_set_local_animation(lua_State *L) { //NO_MAP_LOCK_REQUIRED; @@ -431,6 +431,36 @@ int ObjectRef::l_set_local_animation(lua_State *L) return 0; } +// set_eye_offset(self, v3f first pv, v3f third pv) +int ObjectRef::l_set_eye_offset(lua_State *L) +{ + //NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + Player *player = getplayer(ref); + if (player == NULL) + return 0; + // Do it + v3f offset_first = v3f(0, 0, 0); + v3f offset_third = v3f(0, 0, 0); + + if(!lua_isnil(L, 2)) + offset_first = read_v3f(L, 2); + if(!lua_isnil(L, 3)) + offset_third = read_v3f(L, 3); + + // Prevent abuse of offset values (keep player always visible) + offset_third.X = rangelim(offset_third.X,-10,10); + offset_third.Z = rangelim(offset_third.Z,-5,5); + /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */ + offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS + + if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third)) + return 0; + + lua_pushboolean(L, true); + return 0; +} + // set_bone_position(self, std::string bone, v3f position, v3f rotation) int ObjectRef::l_set_bone_position(lua_State *L) { @@ -1296,5 +1326,6 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, set_sky), luamethod(ObjectRef, override_day_night_ratio), luamethod(ObjectRef, set_local_animation), + luamethod(ObjectRef, set_eye_offset), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index be1068c1..f6070585 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -231,9 +231,12 @@ private: // override_day_night_ratio(self, type, list) static int l_override_day_night_ratio(lua_State *L); - // set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) + // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed) static int l_set_local_animation(lua_State *L); + // set_eye_offset(self, v3f first pv, v3f third pv) + static int l_set_eye_offset(lua_State *L); + public: ObjectRef(ServerActiveObject *object); diff --git a/src/server.cpp b/src/server.cpp index 4f42cfab..cbb9f427 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3502,6 +3502,20 @@ void Server::SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 m_clients.send(peer_id, 0, data, true); } +void Server::SendEyeOffset(u16 peer_id, v3f first, v3f third) +{ + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_EYE_OFFSET); + writeV3F1000(os, first); + writeV3F1000(os, third); + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8 *)s.c_str(), s.size()); + // Send as reliable + m_clients.send(peer_id, 0, data, true); +} void Server::SendPlayerPrivileges(u16 peer_id) { Player *player = m_env->getPlayer(peer_id); @@ -4605,6 +4619,15 @@ bool Server::setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f return true; } +bool Server::setPlayerEyeOffset(Player *player, v3f first, v3f third) +{ + if (!player) + return false; + + SendEyeOffset(player->peer_id, first, third); + return true; +} + bool Server::setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { diff --git a/src/server.h b/src/server.h index c796fc82..23194a3f 100644 --- a/src/server.h +++ b/src/server.h @@ -323,6 +323,7 @@ public: { return m_con.GetPeerAddress(peer_id); } bool setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed); + bool setPlayerEyeOffset(Player *player, v3f first, v3f third); bool setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); @@ -364,6 +365,7 @@ private: void SendPlayerBreath(u16 peer_id); void SendMovePlayer(u16 peer_id); void SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed); + void SendEyeOffset(u16 peer_id, v3f first, v3f third); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname); From 8b02a015eb7630c25e255ffe400bb714d023609b Mon Sep 17 00:00:00 2001 From: BlockMen Date: Sat, 12 Apr 2014 13:50:22 +0200 Subject: [PATCH 43/53] Use integers instead of float values --- src/client.cpp | 8 ++-- src/clientserver.h | 8 ++-- src/content_cao.cpp | 61 +++++++++++++++++++------------ src/player.h | 2 +- src/script/common/c_converter.cpp | 13 +++++++ src/script/common/c_converter.h | 1 + src/script/lua_api/l_object.cpp | 4 +- src/server.cpp | 12 +++--- src/server.h | 4 +- 9 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index dbe95906..72964026 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1922,10 +1922,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); - player->local_animations[0] = readV2F1000(is); - player->local_animations[1] = readV2F1000(is); - player->local_animations[2] = readV2F1000(is); - player->local_animations[3] = readV2F1000(is); + player->local_animations[0] = readV2S32(is); + player->local_animations[1] = readV2S32(is); + player->local_animations[2] = readV2S32(is); + player->local_animations[3] = readV2S32(is); player->local_animation_speed = readF1000(is); } else if(command == TOCLIENT_EYE_OFFSET) diff --git a/src/clientserver.h b/src/clientserver.h index a8cd2ea7..1f2e19e4 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -534,10 +534,10 @@ enum ToClientCommand TOCLIENT_LOCAL_PLAYER_ANIMATIONS = 0x51, /* u16 command - v2f1000 stand/idle - v2f1000 walk - v2f1000 dig - v2f1000 walk+dig + v2s32 stand/idle + v2s32 walk + v2s32 dig + v2s32 walk+dig f1000 frame_speed */ diff --git a/src/content_cao.cpp b/src/content_cao.cpp index dbaf13cc..5f53fd64 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -581,7 +581,7 @@ private: v2s16 m_tx_basepos; bool m_initial_tx_basepos_set; bool m_tx_select_horiz_by_yawpitch; - v2f m_animation_range; + v2s32 m_animation_range; int m_animation_speed; int m_animation_blend; std::map > m_bone_position; // stores position and rotation for each bone name @@ -624,7 +624,7 @@ public: m_tx_basepos(0,0), m_initial_tx_basepos_set(false), m_tx_select_horiz_by_yawpitch(false), - m_animation_range(v2f(0,0)), + m_animation_range(v2s32(0,0)), m_animation_speed(15), m_animation_blend(0), m_bone_position(std::map >()), @@ -1098,41 +1098,51 @@ public: if(controls.up || controls.down || controls.left || controls.right) walking = true; - m_animation_speed = player->local_animation_speed; + f32 new_speed = player->local_animation_speed; + v2s32 new_anim = v2s32(0,0); + bool allow_update = false; + if(!player->touching_ground && g_settings->getBool("free_move") && m_gamedef->checkLocalPrivilege("fly") && g_settings->getBool("fast_move") && m_gamedef->checkLocalPrivilege("fast")) - m_animation_speed *= 1.5; + new_speed *= 1.5; if(controls.sneak && walking) - m_animation_speed /= 2; - - player->last_animation_speed = m_animation_speed; + new_speed /= 2; if(walking && (controls.LMB || controls.RMB)) { - m_animation_range = player->local_animations[3]; + new_anim = player->local_animations[3]; player->last_animation = WD_ANIM; } else if(walking) { - m_animation_range = player->local_animations[1]; + new_anim = player->local_animations[1]; player->last_animation = WALK_ANIM; } else if(controls.LMB || controls.RMB) { - m_animation_range = player->local_animations[2]; + new_anim = player->local_animations[2]; player->last_animation = DIG_ANIM; } + if ((new_anim.X + new_anim.Y) > 0) { + allow_update = true; + m_animation_range = new_anim; + m_animation_speed = new_speed; + player->last_animation_speed = m_animation_speed; + } else { + player->last_animation = NO_ANIM; + } // reset animation when no input detected if (!walking && !controls.LMB && !controls.RMB) { player->last_animation = NO_ANIM; if (old_anim != NO_ANIM) { m_animation_range = player->local_animations[0]; - updateAnimation(); + updateAnimation(); } } // Update local player animations - if ((player->last_animation != old_anim && player->last_animation != NO_ANIM) || m_animation_speed != old_anim_speed) - updateAnimation(); + if ((player->last_animation != old_anim || m_animation_speed != old_anim_speed) && + player->last_animation != NO_ANIM && allow_update) + updateAnimation(); } else { m_is_visible = false; @@ -1501,8 +1511,7 @@ public: { if(m_animated_meshnode == NULL) return; - - m_animated_meshnode->setFrameLoop((int)m_animation_range.X, (int)m_animation_range.Y); + m_animated_meshnode->setFrameLoop(m_animation_range.X, m_animation_range.Y); m_animated_meshnode->setAnimationSpeed(m_animation_speed); m_animated_meshnode->setTransitionTime(m_animation_blend); } @@ -1775,24 +1784,30 @@ public: } else if(cmd == GENERIC_CMD_SET_ANIMATION) { - if (!m_is_local_player) { - m_animation_range = readV2F1000(is); + // TODO: change frames send as v2s32 value + v2f range = readV2F1000(is); + if (!m_is_local_player) { + m_animation_range = v2s32((s32)range.X, (s32)range.Y); m_animation_speed = readF1000(is); m_animation_blend = readF1000(is); updateAnimation(); } else { LocalPlayer *player = m_env->getLocalPlayer(); if(player->last_animation == NO_ANIM) { - m_animation_range = readV2F1000(is); + m_animation_range = v2s32((s32)range.X, (s32)range.Y); m_animation_speed = readF1000(is); m_animation_blend = readF1000(is); } - // update animation only if object is not player - // or the received animation is not registered - if(m_animation_range.X != player->local_animations[1].X && - m_animation_range.X != player->local_animations[2].X && - m_animation_range.X != player->local_animations[3].X) + // update animation only if local animations present + // and received animation is not unknown + int frames = 0; + for (int i = 0;i<4;i++) { + frames += (int)player->local_animations[i].Y; + } + if(frames < 1) { + player->last_animation = NO_ANIM; updateAnimation(); + } } } else if(cmd == GENERIC_CMD_SET_BONE_POSITION) diff --git a/src/player.h b/src/player.h index b9783997..dce16743 100644 --- a/src/player.h +++ b/src/player.h @@ -269,7 +269,7 @@ public: bool physics_override_sneak; bool physics_override_sneak_glitch; - v2f local_animations[4]; + v2s32 local_animations[4]; float local_animation_speed; u16 hp; diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index df86f2da..b2ef0573 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -59,6 +59,19 @@ v2s16 read_v2s16(lua_State *L, int index) return p; } +v2s32 read_v2s32(lua_State *L, int index) +{ + v2s32 p; + luaL_checktype(L, index, LUA_TTABLE); + lua_getfield(L, index, "x"); + p.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "y"); + p.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + return p; +} + v2f read_v2f(lua_State *L, int index) { v2f p; diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index ab008312..0c051a80 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -75,6 +75,7 @@ v3s16 check_v3s16 (lua_State *L, int index); v3f read_v3f (lua_State *L, int index); v2f read_v2f (lua_State *L, int index); v2s16 read_v2s16 (lua_State *L, int index); +v2s32 read_v2s32 (lua_State *L, int index); video::SColor readARGB8 (lua_State *L, int index); aabb3f read_aabb3f (lua_State *L, int index, f32 scale); v3s16 read_v3s16 (lua_State *L, int index); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 8f2bde03..5e3ddd23 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -415,10 +415,10 @@ int ObjectRef::l_set_local_animation(lua_State *L) if (player == NULL) return 0; // Do it - v2f frames[4]; + v2s32 frames[4]; for (int i=0;i<4;i++) { if(!lua_isnil(L, 2+1)) - frames[i] = read_v2f(L, 2+i); + frames[i] = read_v2s32(L, 2+i); } float frame_speed = 30; if(!lua_isnil(L, 6)) diff --git a/src/server.cpp b/src/server.cpp index cbb9f427..ebde0d9e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3484,15 +3484,15 @@ void Server::SendMovePlayer(u16 peer_id) m_clients.send(peer_id, 0, data, true); } -void Server::SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed) +void Server::SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed) { std::ostringstream os(std::ios_base::binary); writeU16(os, TOCLIENT_LOCAL_PLAYER_ANIMATIONS); - writeV2F1000(os, animation_frames[0]); - writeV2F1000(os, animation_frames[1]); - writeV2F1000(os, animation_frames[2]); - writeV2F1000(os, animation_frames[3]); + writeV2S32(os, animation_frames[0]); + writeV2S32(os, animation_frames[1]); + writeV2S32(os, animation_frames[2]); + writeV2S32(os, animation_frames[3]); writeF1000(os, animation_speed); // Make data buffer @@ -4610,7 +4610,7 @@ void Server::hudSetHotbarSelectedImage(Player *player, std::string name) { SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name); } -bool Server::setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed) +bool Server::setLocalPlayerAnimations(Player *player, v2s32 animation_frames[4], f32 frame_speed) { if (!player) return false; diff --git a/src/server.h b/src/server.h index 23194a3f..4cfc879c 100644 --- a/src/server.h +++ b/src/server.h @@ -322,7 +322,7 @@ public: inline Address getPeerAddress(u16 peer_id) { return m_con.GetPeerAddress(peer_id); } - bool setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed); + bool setLocalPlayerAnimations(Player *player, v2s32 animation_frames[4], f32 frame_speed); bool setPlayerEyeOffset(Player *player, v3f first, v3f third); bool setSky(Player *player, const video::SColor &bgcolor, @@ -364,7 +364,7 @@ private: void SendPlayerHP(u16 peer_id); void SendPlayerBreath(u16 peer_id); void SendMovePlayer(u16 peer_id); - void SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed); + void SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed); void SendEyeOffset(u16 peer_id, v3f first, v3f third); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); From b04872d96b54f0a22a972d3a0f16ccef84972d3f Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sun, 13 Apr 2014 17:47:58 -0400 Subject: [PATCH 44/53] Reorder initialization of member variables to make GCC happy --- src/localplayer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 264463d3..15a208b8 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -43,6 +43,10 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): last_pitch(0), last_yaw(0), last_keyPressed(0), + camera_mode(0), + eye_offset_first(v3f(0,0,0)), + eye_offset_third(v3f(0,0,0)), + last_animation(NO_ANIM), hotbar_image(""), hotbar_selected_image(""), m_sneak_node(32767,32767,32767), @@ -50,11 +54,7 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_need_to_get_new_sneak_node(true), - m_can_jump(false), - camera_mode(0), - last_animation(NO_ANIM), - eye_offset_first(v3f(0,0,0)), - eye_offset_third(v3f(0,0,0)) + m_can_jump(false) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points From dcafad2f736aa9b7174bdf7313735d89b981e0c6 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sun, 13 Apr 2014 17:50:46 -0400 Subject: [PATCH 45/53] Add checks for nil in minetest.after --- builtin/misc.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builtin/misc.lua b/builtin/misc.lua index 1d5e146c..f91f5e09 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -21,6 +21,8 @@ minetest.register_globalstep(function(dtime) end) function minetest.after(time, func, ...) + assert(tonumber(time) and type(func) == "function", + "Invalid minetest.after invocation") table.insert(minetest.timers_to_add, {time=time, func=func, args={...}}) end From d436502fa499255236350fc9204f9c508414704e Mon Sep 17 00:00:00 2001 From: Sfan5 Date: Mon, 14 Apr 2014 18:03:28 +0200 Subject: [PATCH 46/53] Fix problem with newer MinGW runtimes --- src/porting.cpp | 3 ++- src/porting.h | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/porting.cpp b/src/porting.cpp index b0a1843e..e7bef1d3 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., See comments in porting.h */ +#include "porting.h" + #if defined(__APPLE__) #include #include "CoreFoundation/CoreFoundation.h" @@ -37,7 +39,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif -#include "porting.h" #include "config.h" #include "debug.h" #include "filesys.h" diff --git a/src/porting.h b/src/porting.h index 9024570b..aaabce4e 100644 --- a/src/porting.h +++ b/src/porting.h @@ -24,6 +24,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef PORTING_HEADER #define PORTING_HEADER +#ifdef _WIN32 + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + #define _WIN32_WINNT 0x0501 // We need to do this before any other headers + // because those might include sdkddkver.h which defines _WIN32_WINNT if not already set +#endif + #include #include "irrlichttypes.h" // u32 #include "debug.h" @@ -42,9 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc., //#define ALIGNOF(type) offsetof (alignment_trick, member) #ifdef _WIN32 - #ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0501 - #endif #include #define sleep_ms(x) Sleep(x) From 118e2ae865bd7a0020586ef72d05bf14d66f4eae Mon Sep 17 00:00:00 2001 From: Sfan5 Date: Tue, 15 Apr 2014 19:49:32 +0200 Subject: [PATCH 47/53] Fix all warnings reported by clang --- src/camera.cpp | 1 - src/camera.h | 3 +-- src/cguittfont/irrUString.h | 16 ++++++++-------- src/clientiface.h | 6 +++--- src/clientobject.h | 2 +- src/clouds.h | 1 - src/connection.cpp | 5 ++--- src/connection.h | 5 +---- src/content_cao.cpp | 9 ++++----- src/emerge.cpp | 2 +- src/environment.cpp | 5 ++--- src/environment.h | 1 - src/game.cpp | 2 +- src/guiVolumeChange.cpp | 3 +-- src/guiVolumeChange.h | 6 +----- src/localplayer.cpp | 4 ++-- src/localplayer.h | 6 +++--- src/main.cpp | 1 - src/map.cpp | 4 +++- src/mapgen.h | 2 +- src/mapgen_indev.cpp | 6 +++--- src/mapgen_indev.h | 2 +- src/player.h | 7 ++++++- src/script/cpp_api/s_item.h | 2 +- src/script/lua_api/l_mapgen.cpp | 4 ++-- src/shader.cpp | 6 +----- src/sky.h | 1 - 27 files changed, 49 insertions(+), 63 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 6fbd1dd8..b49e8e74 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -44,7 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc., Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, IGameDef *gamedef): - m_smgr(smgr), m_playernode(NULL), m_headnode(NULL), m_cameranode(NULL), diff --git a/src/camera.h b/src/camera.h index 82c8d4be..d1c3b59d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -136,8 +136,7 @@ public: void drawWieldedTool(); private: - // Scene manager and nodes - scene::ISceneManager* m_smgr; + // Nodes scene::ISceneNode* m_playernode; scene::ISceneNode* m_headnode; scene::ICameraSceneNode* m_cameranode; diff --git a/src/cguittfont/irrUString.h b/src/cguittfont/irrUString.h index 21109ea4..132a35ee 100644 --- a/src/cguittfont/irrUString.h +++ b/src/cguittfont/irrUString.h @@ -3395,7 +3395,7 @@ inline ustring16 operator+(const ustring16& left, const short ri template inline ustring16 operator+(const short left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3415,7 +3415,7 @@ inline ustring16 operator+(const ustring16& left, const unsigned template inline ustring16 operator+(const unsigned short left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3435,7 +3435,7 @@ inline ustring16 operator+(const ustring16& left, const int righ template inline ustring16 operator+(const int left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3455,7 +3455,7 @@ inline ustring16 operator+(const ustring16& left, const unsigned template inline ustring16 operator+(const unsigned int left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3475,7 +3475,7 @@ inline ustring16 operator+(const ustring16& left, const long rig template inline ustring16 operator+(const long left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3495,7 +3495,7 @@ inline ustring16 operator+(const ustring16& left, const unsigned template inline ustring16 operator+(const unsigned long left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3515,7 +3515,7 @@ inline ustring16 operator+(const ustring16& left, const float ri template inline ustring16 operator+(const float left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } @@ -3535,7 +3535,7 @@ inline ustring16 operator+(const ustring16& left, const double r template inline ustring16 operator+(const double left, const ustring16& right) { - ustring16 ret(core::stringc(left)); + ustring16 ret((core::stringc(left))); ret += right; return ret; } diff --git a/src/clientiface.h b/src/clientiface.h index 95f8bd30..752e2bb8 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -141,6 +141,8 @@ namespace con { class Connection; } +#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) + enum ClientState { Invalid, @@ -219,7 +221,6 @@ public: m_nearest_unsent_d(0), m_nearest_unsent_reset_timer(0.0), m_excess_gotblocks(0), - m_nothing_to_send_counter(0), m_nothing_to_send_pause_timer(0.0), m_name(""), m_version_major(0), @@ -355,7 +356,6 @@ private: u32 m_excess_gotblocks; // CPU usage optimization - u32 m_nothing_to_send_counter; float m_nothing_to_send_pause_timer; /* @@ -433,7 +433,7 @@ public: { assert(m_env == 0); m_env = env; } static std::string state2Name(ClientState state) { - assert(state < sizeof(statenames)); + assert((int) state < ARRAYSIZE(statenames)); return statenames[state]; } diff --git a/src/clientobject.h b/src/clientobject.h index 613c635a..233617b5 100644 --- a/src/clientobject.h +++ b/src/clientobject.h @@ -55,7 +55,7 @@ public: virtual void updateLight(u8 light_at_pos){} virtual v3s16 getLightPosition(){return v3s16(0,0,0);} virtual core::aabbox3d* getSelectionBox(){return NULL;} - virtual core::aabbox3d* getCollisionBox(){return NULL;} + virtual bool getCollisionBox(aabb3f *toset){return false;} virtual bool collideWithObjects(){return false;} virtual v3f getPosition(){return v3f(0,0,0);} virtual scene::IMeshSceneNode *getMeshSceneNode(){return NULL;} diff --git a/src/clouds.h b/src/clouds.h index d718e56b..a6883a44 100644 --- a/src/clouds.h +++ b/src/clouds.h @@ -76,7 +76,6 @@ private: video::SMaterial m_material; core::aabbox3d m_box; float m_cloud_y; - float m_brightness; video::SColorf m_color; u32 m_seed; v2f m_camera_pos; diff --git a/src/connection.cpp b/src/connection.cpp index c77ee7f4..32634ac8 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -212,7 +212,7 @@ SharedBuffer makeReliablePacket( ReliablePacketBuffer */ -ReliablePacketBuffer::ReliablePacketBuffer(): m_list_size(0),writeptr(0) {} +ReliablePacketBuffer::ReliablePacketBuffer(): m_list_size(0) {} void ReliablePacketBuffer::print() { @@ -1941,8 +1941,7 @@ void ConnectionSendThread::sendAsPacket(u16 peer_id, u8 channelnum, ConnectionReceiveThread::ConnectionReceiveThread(Connection* parent, unsigned int max_packet_size) : - m_connection(parent), - m_max_packet_size(max_packet_size) + m_connection(parent) { } diff --git a/src/connection.h b/src/connection.h index 0f936eb3..43fd2fb8 100644 --- a/src/connection.h +++ b/src/connection.h @@ -339,13 +339,11 @@ private: RPBSearchResult findPacket(u16 seqnum); std::list m_list; - u16 m_list_size; + u32 m_list_size; u16 m_oldest_non_answered_ack; JMutex m_list_mutex; - - unsigned int writeptr; }; /* @@ -975,7 +973,6 @@ private: Connection* m_connection; - unsigned int m_max_packet_size; }; class Connection diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 5f53fd64..10aa22e7 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -166,7 +166,7 @@ public: void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr); - void removeFromScene(); + void removeFromScene(bool permanent); void updateLight(u8 light_at_pos); v3s16 getLightPosition(); void updateNodePos(); @@ -236,7 +236,7 @@ void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, updateNodePos(); } -void TestCAO::removeFromScene() +void TestCAO::removeFromScene(bool permanent) { if(m_node == NULL) return; @@ -310,7 +310,7 @@ public: void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr); - void removeFromScene(); + void removeFromScene(bool permanent); void updateLight(u8 light_at_pos); v3s16 getLightPosition(); void updateNodePos(); @@ -412,7 +412,7 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, updateTexture(); } -void ItemCAO::removeFromScene() +void ItemCAO::removeFromScene(bool permanent) { if(m_node == NULL) return; @@ -648,7 +648,6 @@ public: bool getCollisionBox(aabb3f *toset) { if (m_prop.physical) { - aabb3f retval; //update collision box toset->MinEdge = m_prop.collisionbox.MinEdge * BS; toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS; diff --git a/src/emerge.cpp b/src/emerge.cpp index c26fab83..443d7038 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -465,7 +465,7 @@ void *EmergeThread::Thread() { v3s16 last_tried_pos(-32768,-32768,-32768); // For error output v3s16 p; - u8 flags; + u8 flags = 0; map = (ServerMap *)&(m_server->m_env->getMap()); emerge = m_server->m_emerge; diff --git a/src/environment.cpp b/src/environment.cpp index 630f8d21..bc1b59d8 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -314,7 +314,6 @@ ServerEnvironment::ServerEnvironment(ServerMap *map, m_map(map), m_script(scriptIface), m_gamedef(gamedef), - m_random_spawn_timer(3), m_send_recommended_timer(0), m_active_block_interval_overload_skip(0), m_game_time(0), @@ -1097,7 +1096,7 @@ void ServerEnvironment::step(float dtime) continue; // Move - player->move(dtime, *m_map, 100*BS); + player->move(dtime, this, 100*BS); } } @@ -2395,7 +2394,7 @@ void ClientEnvironment::step(float dtime) if(player->isLocal() == false) { // Move - player->move(dtime, *m_map, 100*BS); + player->move(dtime, this, 100*BS); } diff --git a/src/environment.h b/src/environment.h index d99e27ba..48d099bf 100644 --- a/src/environment.h +++ b/src/environment.h @@ -374,7 +374,6 @@ private: // Outgoing network message buffer for active objects std::list m_active_object_messages; // Some timers - float m_random_spawn_timer; // used for experimental code float m_send_recommended_timer; IntervalLimiter m_object_management_interval; // List of active blocks diff --git a/src/game.cpp b/src/game.cpp index 2e8d3761..1ad06acb 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -132,7 +132,7 @@ struct LocalFormspecHandler : public TextDest m_client = client; } - void gotText(std::string message) { + void gotText(std::wstring message) { errorstream << "LocalFormspecHandler::gotText old style message received" << std::endl; } diff --git a/src/guiVolumeChange.cpp b/src/guiVolumeChange.cpp index 5e7476bb..f31c650f 100644 --- a/src/guiVolumeChange.cpp +++ b/src/guiVolumeChange.cpp @@ -41,8 +41,7 @@ GUIVolumeChange::GUIVolumeChange(gui::IGUIEnvironment* env, IMenuManager *menumgr, Client* client ): - GUIModalMenu(env, parent, id, menumgr), - m_client(client) + GUIModalMenu(env, parent, id, menumgr) { } diff --git a/src/guiVolumeChange.h b/src/guiVolumeChange.h index 5258ee10..9f8199fa 100644 --- a/src/guiVolumeChange.h +++ b/src/guiVolumeChange.h @@ -44,11 +44,7 @@ public: bool OnEvent(const SEvent& event); - bool pausesGame(){ return true; } - -private: - Client* m_client; - + bool pausesGame() { return true; } }; #endif diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 15a208b8..e545dc42 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -65,7 +65,7 @@ LocalPlayer::~LocalPlayer() { } -void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d, +void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, std::list *collision_info) { Map *map = &env->getMap(); @@ -360,7 +360,7 @@ void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d, m_can_jump = false; } -void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d) +void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d) { move(dtime, env, pos_max_d, NULL); } diff --git a/src/localplayer.h b/src/localplayer.h index 67deb936..38e7a4cd 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "player.h" #include -class ClientEnvironment; +class Environment; class ClientActiveObject; @@ -46,9 +46,9 @@ public: v3f overridePosition; - void move(f32 dtime, ClientEnvironment *env, f32 pos_max_d, + void move(f32 dtime, Environment *env, f32 pos_max_d); + void move(f32 dtime, Environment *env, f32 pos_max_d, std::list *collision_info); - void move(f32 dtime, ClientEnvironment *env, f32 pos_max_d); void applyControl(float dtime); diff --git a/src/main.cpp b/src/main.cpp index baaf8ebd..c93af0d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,7 +360,6 @@ public: s32 mouse_wheel; private: - IrrlichtDevice *m_device; // The current state of keys KeyList keyIsDown; diff --git a/src/map.cpp b/src/map.cpp index 22ea41e0..ec97fedf 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2596,6 +2596,7 @@ bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) // Sector metadata is loaded from disk if not already loaded. ServerMapSector *sector = createSector(sectorpos); assert(sector); + (void) sector; for(s16 y=blockpos_min.Y-extra_borders.Y; y<=blockpos_max.Y+extra_borders.Y; y++) @@ -3261,12 +3262,13 @@ std::string ServerMap::getSectorDir(v2s16 pos, int layout) return m_savedir + DIR_DELIM + "sectors2" + DIR_DELIM + cc; default: assert(false); + return ""; } } v2s16 ServerMap::getSectorPos(std::string dirname) { - unsigned int x, y; + unsigned int x = 0, y = 0; int r; std::string component; fs::RemoveLastPathComponent(dirname, &component, 1); diff --git a/src/mapgen.h b/src/mapgen.h index 9bc162fe..3c897e02 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -209,7 +209,7 @@ Ore *createOre(OreType type); enum DecorationType { - DECO_SIMPLE, + DECO_SIMPLE = 1, DECO_SCHEMATIC, DECO_LSYSTEM }; diff --git a/src/mapgen_indev.cpp b/src/mapgen_indev.cpp index ac5b4e81..f0154715 100644 --- a/src/mapgen_indev.cpp +++ b/src/mapgen_indev.cpp @@ -26,9 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc., /////////////////////////////////////////////////////////////////////////////// -void NoiseIndev::init(NoiseIndevParams *np, int seed, int sx, int sy, int sz) { - Noise::init((NoiseParams*)np, seed, sx, sy, sz); - this->npindev = np; +void NoiseIndev::init(NoiseParams *np, int seed, int sx, int sy, int sz) { + Noise::init(np, seed, sx, sy, sz); + this->npindev = (NoiseIndevParams*) np; } NoiseIndev::NoiseIndev(NoiseIndevParams *np, int seed, int sx, int sy) : Noise(np, seed, sx, sy) { diff --git a/src/mapgen_indev.h b/src/mapgen_indev.h index a5b0a667..d8be7dce 100644 --- a/src/mapgen_indev.h +++ b/src/mapgen_indev.h @@ -61,7 +61,7 @@ public: virtual ~NoiseIndev() {}; NoiseIndev(NoiseIndevParams *np, int seed, int sx, int sy); NoiseIndev(NoiseIndevParams *np, int seed, int sx, int sy, int sz); - void init(NoiseIndevParams *np, int seed, int sx, int sy, int sz); + void init(NoiseParams *np, int seed, int sx, int sy, int sz); void transformNoiseMapFarScale(float xx = 0, float yy = 0, float zz = 0); }; diff --git a/src/player.h b/src/player.h index dce16743..4c5939d3 100644 --- a/src/player.h +++ b/src/player.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include "inventory.h" #include "constants.h" // BS +#include #define PLAYERNAME_SIZE 20 @@ -88,6 +89,7 @@ class IGameDef; struct CollisionInfo; class PlayerSAO; struct HudElement; +class Environment; class Player { @@ -96,7 +98,10 @@ public: Player(IGameDef *gamedef); virtual ~Player() = 0; - virtual void move(f32 dtime, Map &map, f32 pos_max_d) + virtual void move(f32 dtime, Environment *env, f32 pos_max_d) + {} + virtual void move(f32 dtime, Environment *env, f32 pos_max_d, + std::list *collision_info) {} v3f getSpeed() diff --git a/src/script/cpp_api/s_item.h b/src/script/cpp_api/s_item.h index cca1641f..88cc1909 100644 --- a/src/script/cpp_api/s_item.h +++ b/src/script/cpp_api/s_item.h @@ -30,7 +30,7 @@ struct ItemDefinition; class LuaItemStack; class ModApiItemMod; class InventoryList; -class InventoryLocation; +struct InventoryLocation; class ScriptApiItem : virtual public ScriptApiBase diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 56109a9d..9fbb46ee 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -324,8 +324,8 @@ int ModApiMapgen::l_register_decoration(lua_State *L) BiomeDefManager *bdef = emerge->biomedef; enum DecorationType decotype = (DecorationType)getenumfield(L, index, - "deco_type", es_DecorationType, -1); - if (decotype == -1) { + "deco_type", es_DecorationType, 0); + if (decotype == 0) { errorstream << "register_decoration: unrecognized " "decoration placement type"; return 0; diff --git a/src/shader.cpp b/src/shader.cpp index 4006e256..4013add6 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -210,8 +210,7 @@ public: class MainShaderConstantSetter : public IShaderConstantSetter { public: - MainShaderConstantSetter(IrrlichtDevice *device): - m_device(device) + MainShaderConstantSetter(IrrlichtDevice *device) {} ~MainShaderConstantSetter() {} @@ -255,9 +254,6 @@ public: services->setVertexShaderConstant(world.pointer(), 8, 4); } - -private: - IrrlichtDevice *m_device; }; /* diff --git a/src/sky.h b/src/sky.h index 06a99310..c906bd32 100644 --- a/src/sky.h +++ b/src/sky.h @@ -125,7 +125,6 @@ private: video::SColor m_skycolor; video::SColorf m_cloudcolor_f; v3f m_stars[SKY_STAR_COUNT]; - u16 m_star_indices[SKY_STAR_COUNT*4]; video::S3DVertex m_star_vertices[SKY_STAR_COUNT*4]; LocalPlayer* m_player; }; From 54ffe2e5de9ce44129f84f4748743f893b75fda7 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 15 Apr 2014 16:07:53 -0400 Subject: [PATCH 48/53] Use binary operators rather than "Python modulo" in decoding block positions --- src/database.cpp | 38 +++++++++++++++++--------------------- src/database.h | 4 ++-- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/database.cpp b/src/database.cpp index e3d92f91..cf208be8 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -20,33 +20,29 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "database.h" #include "irrlichttypes.h" -static s32 unsignedToSigned(s32 i, s32 max_positive) +static inline s16 unsigned_to_signed(u16 i, u16 max_positive) { - if(i < max_positive) + if (i < max_positive) { return i; - else - return i - 2*max_positive; + } else { + return i - (max_positive * 2); + } } -// modulo of a negative number does not work consistently in C -static s64 pythonmodulo(s64 i, s64 mod) + +s64 Database::getBlockAsInteger(const v3s16 pos) const { - if(i >= 0) - return i % mod; - return mod - ((-i) % mod); -} - -s64 Database::getBlockAsInteger(const v3s16 pos) { - return (u64) pos.Z * 16777216 + - (u64) pos.Y * 4096 + + return (u64) pos.Z * 0x1000000 + + (u64) pos.Y * 0x1000 + (u64) pos.X; } -v3s16 Database::getIntegerAsBlock(s64 i) { - s32 x = unsignedToSigned(pythonmodulo(i, 4096), 2048); - i = (i - x) / 4096; - s32 y = unsignedToSigned(pythonmodulo(i, 4096), 2048); - i = (i - y) / 4096; - s32 z = unsignedToSigned(pythonmodulo(i, 4096), 2048); - return v3s16(x,y,z); +v3s16 Database::getIntegerAsBlock(const s64 i) const +{ + v3s16 pos; + pos.Z = unsigned_to_signed((i >> 24) & 0xFFF, 0x1000 / 2); + pos.Y = unsigned_to_signed((i >> 12) & 0xFFF, 0x1000 / 2); + pos.X = unsigned_to_signed((i ) & 0xFFF, 0x1000 / 2); + return pos; } + diff --git a/src/database.h b/src/database.h index 4ce80ed9..a8686137 100644 --- a/src/database.h +++ b/src/database.h @@ -34,8 +34,8 @@ public: virtual void saveBlock(MapBlock *block)=0; virtual MapBlock* loadBlock(v3s16 blockpos)=0; - s64 getBlockAsInteger(const v3s16 pos); - v3s16 getIntegerAsBlock(s64 i); + s64 getBlockAsInteger(const v3s16 pos) const; + v3s16 getIntegerAsBlock(const s64 i) const; virtual void listAllLoadableBlocks(std::list &dst)=0; virtual int Initialized(void)=0; virtual ~Database() {}; From a2003b0d553c7223a61c75e5dad79ea68e058ba2 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 15 Apr 2014 16:25:04 -0400 Subject: [PATCH 49/53] Use bit shifts rather than multiplication in block position encoding --- src/database.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database.cpp b/src/database.cpp index cf208be8..15579a7f 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -32,9 +32,9 @@ static inline s16 unsigned_to_signed(u16 i, u16 max_positive) s64 Database::getBlockAsInteger(const v3s16 pos) const { - return (u64) pos.Z * 0x1000000 + - (u64) pos.Y * 0x1000 + - (u64) pos.X; + return (((u64) pos.Z) << 24) + + (((u64) pos.Y) << 12) + + ((u64) pos.X); } v3s16 Database::getIntegerAsBlock(const s64 i) const From db60ae0459a7711bdaca2dff94c2e87e8e97796d Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Wed, 16 Apr 2014 16:56:54 +0200 Subject: [PATCH 50/53] Fix invalid liquid lighting. --- client/shaders/liquids_shader/opengl_fragment.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/shaders/liquids_shader/opengl_fragment.glsl b/client/shaders/liquids_shader/opengl_fragment.glsl index e4082259..5bc932ad 100644 --- a/client/shaders/liquids_shader/opengl_fragment.glsl +++ b/client/shaders/liquids_shader/opengl_fragment.glsl @@ -91,5 +91,5 @@ vec4 base = texture2D(baseTexture, uv).rgba; float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0)); alpha = mix(alpha, 0.0, d); } - gl_FragColor = vec4(color.rgb, alpha); + gl_FragColor = vec4(col.rgb, alpha); } From 674be38fc262aab78ed75141c70e5c02830ca80d Mon Sep 17 00:00:00 2001 From: Sfan5 Date: Tue, 8 Apr 2014 21:39:21 +0200 Subject: [PATCH 51/53] Add redis database backend --- src/CMakeLists.txt | 26 +++++ src/cmake_config.h.in | 1 + src/config.h | 6 ++ src/database-redis.cpp | 224 +++++++++++++++++++++++++++++++++++++++++ src/database-redis.h | 50 +++++++++ src/main.cpp | 9 +- src/map.cpp | 7 ++ 7 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 src/database-redis.cpp create mode 100644 src/database-redis.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24bbe7e1..6836ad6e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -291,6 +291,25 @@ if(ENABLE_LEVELDB) endif(LEVELDB_LIBRARY AND LEVELDB_INCLUDE_DIR) endif(ENABLE_LEVELDB) +set(USE_REDIS 0) + +OPTION(ENABLE_REDIS "Enable redis backend" 1) + +if(ENABLE_REDIS) + find_library(REDIS_LIBRARY hiredis) + find_path(REDIS_INCLUDE_DIR hiredis.h PATH_SUFFIXES hiredis) + message(STATUS "redis library: ${REDIS_LIBRARY}") + message(STATUS "redis headers: ${REDIS_INCLUDE_DIR}") + if(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) + set(USE_REDIS 1) + message(STATUS "redis backend enabled") + include_directories(${REDIS_INCLUDE_DIR}) + else(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) + set(USE_REDIS 0) + message(STATUS "redis not found!") + endif(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) +endif(ENABLE_REDIS) + configure_file( "${PROJECT_SOURCE_DIR}/cmake_config.h.in" "${PROJECT_BINARY_DIR}/cmake_config.h" @@ -368,6 +387,7 @@ set(common_SRCS database-dummy.cpp database-leveldb.cpp database-sqlite3.cpp + database-redis.cpp player.cpp test.cpp sha1.cpp @@ -533,6 +553,9 @@ if(BUILD_CLIENT) if (USE_LEVELDB) target_link_libraries(${PROJECT_NAME} ${LEVELDB_LIBRARY}) endif(USE_LEVELDB) + if (USE_REDIS) + target_link_libraries(${PROJECT_NAME} ${REDIS_LIBRARY}) + endif(USE_REDIS) endif(BUILD_CLIENT) if(BUILD_SERVER) @@ -550,6 +573,9 @@ if(BUILD_SERVER) if (USE_LEVELDB) target_link_libraries(${PROJECT_NAME}server ${LEVELDB_LIBRARY}) endif(USE_LEVELDB) + if (USE_REDIS) + target_link_libraries(${PROJECT_NAME}server ${REDIS_LIBRARY}) + endif(USE_REDIS) if(USE_CURL) target_link_libraries( ${PROJECT_NAME}server diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index 17d3c224..906b3e47 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -14,6 +14,7 @@ #define CMAKE_STATIC_SHAREDIR "@SHAREDIR@" #define CMAKE_USE_LEVELDB @USE_LEVELDB@ #define CMAKE_USE_LUAJIT @USE_LUAJIT@ +#define CMAKE_USE_REDIS @USE_REDIS@ #define CMAKE_VERSION_MAJOR @VERSION_MAJOR@ #define CMAKE_VERSION_MINOR @VERSION_MINOR@ #define CMAKE_VERSION_PATCH @VERSION_PATCH@ diff --git a/src/config.h b/src/config.h index 1558ebe0..8a9d7d63 100644 --- a/src/config.h +++ b/src/config.h @@ -28,6 +28,10 @@ #define USE_LUAJIT 0 #endif +#ifndef USE_REDIS + #define USE_REDIS 0 +#endif + #ifdef USE_CMAKE_CONFIG_H #include "cmake_config.h" #undef PROJECT_NAME @@ -48,6 +52,8 @@ #define USE_LEVELDB CMAKE_USE_LEVELDB #undef USE_LUAJIT #define USE_LUAJIT CMAKE_USE_LUAJIT + #undef USE_REDIS + #define USE_REDIS CMAKE_USE_REDIS #undef VERSION_MAJOR #define VERSION_MAJOR CMAKE_VERSION_MAJOR #undef VERSION_MINOR diff --git a/src/database-redis.cpp b/src/database-redis.cpp new file mode 100644 index 00000000..1d77608f --- /dev/null +++ b/src/database-redis.cpp @@ -0,0 +1,224 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola + +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 "config.h" + +#if USE_REDIS +/* + Redis databases +*/ + + +#include "database-redis.h" +#include + +#include "map.h" +#include "mapsector.h" +#include "mapblock.h" +#include "serialization.h" +#include "main.h" +#include "settings.h" +#include "log.h" + +Database_Redis::Database_Redis(ServerMap *map, std::string savedir) +{ + Settings conf; + conf.readConfigFile((std::string(savedir) + DIR_DELIM + "world.mt").c_str()); + std::string tmp; + try { + tmp = conf.get("redis_address"); + hash = conf.get("redis_hash"); + } catch(SettingNotFoundException e) { + throw SettingNotFoundException("Set redis_address and redis_hash in world.mt to use the redis backend"); + } + const char *addr = tmp.c_str(); + int port = conf.exists("redis_port") ? conf.getU16("redis_port") : 6379; + ctx = redisConnect(addr, port); + if(!ctx) + throw FileNotGoodException("Cannot allocate redis context"); + else if(ctx->err) { + std::string err = std::string("Connection error: ") + ctx->errstr; + redisFree(ctx); + throw FileNotGoodException(err); + } + srvmap = map; +} + +int Database_Redis::Initialized(void) +{ + return 1; +} + +void Database_Redis::beginSave() { + redisReply *reply; + reply = (redisReply*) redisCommand(ctx, "MULTI"); + if(!reply) + throw FileNotGoodException(std::string("redis command 'MULTI' failed: ") + ctx->errstr); + freeReplyObject(reply); +} + +void Database_Redis::endSave() { + redisReply *reply; + reply = (redisReply*) redisCommand(ctx, "EXEC"); + if(!reply) + throw FileNotGoodException(std::string("redis command 'EXEC' failed: ") + ctx->errstr); + freeReplyObject(reply); +} + +void Database_Redis::saveBlock(MapBlock *block) +{ + DSTACK(__FUNCTION_NAME); + /* + Dummy blocks are not written + */ + if(block->isDummy()) + { + return; + } + + // Format used for writing + u8 version = SER_FMT_VER_HIGHEST_WRITE; + // Get destination + v3s16 p3d = block->getPos(); + + /* + [0] u8 serialization version + [1] data + */ + + std::ostringstream o(std::ios_base::binary); + o.write((char*)&version, 1); + // Write basic data + block->serialize(o, version, true); + // Write block to database + std::string tmp1 = o.str(); + std::string tmp2 = i64tos(getBlockAsInteger(p3d)); + + redisReply *reply; + reply = (redisReply*) redisCommand(ctx, "HSET %s %s %b", hash.c_str(), tmp2.c_str(), tmp1.c_str(), tmp1.size()); + if(!reply) + throw FileNotGoodException(std::string("redis command 'HSET %s %s %b' failed: ") + ctx->errstr); + if(reply->type == REDIS_REPLY_ERROR) + throw FileNotGoodException("Failed to store block in Database"); + + // We just wrote it to the disk so clear modified flag + block->resetModified(); +} + +MapBlock* Database_Redis::loadBlock(v3s16 blockpos) +{ + v2s16 p2d(blockpos.X, blockpos.Z); + + std::string tmp = i64tos(getBlockAsInteger(blockpos)); + redisReply *reply; + reply = (redisReply*) redisCommand(ctx, "HGET %s %s", hash.c_str(), tmp.c_str()); + if(!reply) + throw FileNotGoodException(std::string("redis command 'HGET %s %s' failed: ") + ctx->errstr); + + if (reply->type == REDIS_REPLY_STRING && reply->len == 0) { + freeReplyObject(reply); + errorstream << "Blank block data in database (reply->len == 0) (" + << blockpos.X << "," << blockpos.Y << "," << blockpos.Z << ")" << std::endl; + + if (g_settings->getBool("ignore_world_load_errors")) { + errorstream << "Ignoring block load error. Duck and cover! " + << "(ignore_world_load_errors)" << std::endl; + } else { + throw SerializationError("Blank block data in database"); + } + return NULL; + } + + if (reply->type == REDIS_REPLY_STRING) { + /* + Make sure sector is loaded + */ + MapSector *sector = srvmap->createSector(p2d); + + try { + std::istringstream is(std::string(reply->str, reply->len), std::ios_base::binary); + freeReplyObject(reply); // std::string copies the memory so we can already do this here + u8 version = SER_FMT_VER_INVALID; + is.read((char *)&version, 1); + + if (is.fail()) + throw SerializationError("ServerMap::loadBlock(): Failed" + " to read MapBlock version"); + + MapBlock *block = NULL; + bool created_new = false; + block = sector->getBlockNoCreateNoEx(blockpos.Y); + if (block == NULL) + { + block = sector->createBlankBlockNoInsert(blockpos.Y); + created_new = true; + } + + // Read basic data + block->deSerialize(is, version, true); + + // If it's a new block, insert it to the map + if (created_new) + sector->insertBlock(block); + + // We just loaded it from, so it's up-to-date. + block->resetModified(); + } + catch (SerializationError &e) + { + errorstream << "Invalid block data in database" + << " (" << blockpos.X << "," << blockpos.Y << "," << blockpos.Z + << ") (SerializationError): " << e.what() << std::endl; + // TODO: Block should be marked as invalid in memory so that it is + // not touched but the game can run + + if (g_settings->getBool("ignore_world_load_errors")) { + errorstream << "Ignoring block load error. Duck and cover! " + << "(ignore_world_load_errors)" << std::endl; + } else { + throw SerializationError("Invalid block data in database"); + } + } + + return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here + } + return NULL; +} + +void Database_Redis::listAllLoadableBlocks(std::list &dst) +{ + redisReply *reply; + reply = (redisReply*) redisCommand(ctx, "HKEYS %s", hash.c_str()); + if(!reply) + throw FileNotGoodException(std::string("redis command 'HKEYS %s' failed: ") + ctx->errstr); + if(reply->type != REDIS_REPLY_ARRAY) + throw FileNotGoodException("Failed to get keys from database"); + for(size_t i = 0; i < reply->elements; i++) + { + assert(reply->element[i]->type == REDIS_REPLY_STRING); + dst.push_back(getIntegerAsBlock(stoi64(reply->element[i]->str))); + } + freeReplyObject(reply); +} + +Database_Redis::~Database_Redis() +{ + redisFree(ctx); +} +#endif diff --git a/src/database-redis.h b/src/database-redis.h new file mode 100644 index 00000000..da76775d --- /dev/null +++ b/src/database-redis.h @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2014 celeron55, Perttu Ahola + +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 DATABASE_REDIS_HEADER +#define DATABASE_REDIS_HEADER + +#include "config.h" + +#if USE_REDIS + +#include "database.h" +#include +#include + +class ServerMap; + +class Database_Redis : public Database +{ +public: + Database_Redis(ServerMap *map, std::string savedir); + virtual void beginSave(); + virtual void endSave(); + virtual void saveBlock(MapBlock *block); + virtual MapBlock* loadBlock(v3s16 blockpos); + virtual void listAllLoadableBlocks(std::list &dst); + virtual int Initialized(void); + ~Database_Redis(); +private: + ServerMap *srvmap; + redisContext *ctx; + std::string hash; +}; +#endif +#endif diff --git a/src/main.cpp b/src/main.cpp index c93af0d7..bb0c3a27 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,6 +84,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifdef USE_LEVELDB #include "database-leveldb.h" #endif +#if USE_REDIS +#include "database-redis.h" +#endif /* Settings. @@ -1242,7 +1245,7 @@ int main(int argc, char *argv[]) } if (!world_mt.exists("backend")) { errorstream << "Please specify your current backend in world.mt file:" - << std::endl << " backend = {sqlite3|leveldb|dummy}" << std::endl; + << std::endl << " backend = {sqlite3|leveldb|redis|dummy}" << std::endl; return 1; } std::string backend = world_mt.get("backend"); @@ -1257,6 +1260,10 @@ int main(int argc, char *argv[]) else if (migrate_to == "leveldb") new_db = new Database_LevelDB(&(ServerMap&)server.getMap(), world_path); #endif + #if USE_REDIS + else if (migrate_to == "redis") + new_db = new Database_Redis(&(ServerMap&)server.getMap(), world_path); + #endif else { errorstream << "Migration to " << migrate_to << " is not supported" << std::endl; return 1; diff --git a/src/map.cpp b/src/map.cpp index ec97fedf..8f612aea 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -46,6 +46,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #if USE_LEVELDB #include "database-leveldb.h" #endif +#if USE_REDIS +#include "database-redis.h" +#endif #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -2434,6 +2437,10 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer else if (backend == "leveldb") dbase = new Database_LevelDB(this, savedir); #endif + #if USE_REDIS + else if (backend == "redis") + dbase = new Database_Redis(this, savedir); + #endif else throw BaseException("Unknown map backend"); } From 0279f32db742f06d24a9d01c46f7d70c5e570eb2 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 18 Apr 2014 21:08:03 +0400 Subject: [PATCH 52/53] Remove liquid_finite and weather --- builtin/mainmenu.lua | 6 - doc/lua_api.txt | 4 - minetest.conf.example | 14 -- src/biome.cpp | 51 ---- src/constants.h | 6 - src/content_abm.cpp | 212 +--------------- src/defaultsettings.cpp | 5 - src/environment.cpp | 1 - src/environment.h | 3 - src/game.cpp | 8 +- src/map.cpp | 475 ----------------------------------- src/map.h | 7 - src/mapblock.cpp | 12 +- src/mapblock.h | 5 - src/mapgen.cpp | 6 +- src/script/lua_api/l_env.cpp | 25 -- src/script/lua_api/l_env.h | 3 - src/serverlist.cpp | 1 - 18 files changed, 8 insertions(+), 836 deletions(-) diff --git a/builtin/mainmenu.lua b/builtin/mainmenu.lua index e9c8e813..4cd1503d 100644 --- a/builtin/mainmenu.lua +++ b/builtin/mainmenu.lua @@ -714,9 +714,6 @@ function tabbuilder.handle_settings_buttons(fields) if fields["cb_particles"] then engine.setting_set("enable_particles", fields["cb_particles"]) end - if fields["cb_finite_liquid"] then - engine.setting_set("liquid_finite", fields["cb_finite_liquid"]) - end if fields["cb_bumpmapping"] then engine.setting_set("enable_bumpmapping", fields["cb_bumpmapping"]) end @@ -997,9 +994,6 @@ function tabbuilder.tab_settings() .. dump(engine.setting_getbool("preload_item_visuals")) .. "]".. "checkbox[1,2.5;cb_particles;".. fgettext("Enable Particles") .. ";" .. dump(engine.setting_getbool("enable_particles")) .. "]".. - "checkbox[1,3.0;cb_finite_liquid;".. fgettext("Finite Liquid") .. ";" - .. dump(engine.setting_getbool("liquid_finite")) .. "]".. - "checkbox[4.5,0;cb_mipmapping;".. fgettext("Mip-Mapping") .. ";" .. dump(engine.setting_getbool("mip_map")) .. "]".. "checkbox[4.5,0.5;cb_anisotrophic;".. fgettext("Anisotropic Filtering") .. ";" diff --git a/doc/lua_api.txt b/doc/lua_api.txt index b9865ae4..b933caff 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1443,10 +1443,6 @@ minetest.set_node_level(pos, level) ^ set level of leveled node, default level = 1, if totallevel > maxlevel returns rest (total-max). minetest.add_node_level(pos, level) ^ increase level of leveled node by level, default level = 1, if totallevel > maxlevel returns rest (total-max). can be negative for decreasing -minetest.get_heat(pos) -^ heat at pos -minetest.get_humidity(pos) -^ humidity at pos Inventory: minetest.get_inventory(location) -> InvRef diff --git a/minetest.conf.example b/minetest.conf.example index 6b2867c3..548adcce 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -93,24 +93,10 @@ #enable_fog = true # Enable a bit lower water surface; disable for speed (not quite optimized) #new_style_water = false -# Constant volume liquids -#liquid_finite = false # Max liquids processed per step #liquid_loop_max = 10000 # Update liquids every .. recommend for finite: 0.2 #liquid_update = 1.0 -# Relax flowing blocks to source if level near max and N nearby -# source blocks, more realistic, but not true constant. -# values: 0,1,2,3,4 : 0 - disable, 1 - most aggresive -# (for finite liquids) -#liquid_relax = 2 -# Optimization: faster cave flood (and not true constant) -# (for finite liquids) -#liquid_fast_flood = 1 -# Underground water and lava springs, its infnity sources if liquid_finite enabled -#underground_springs = 1 -# Enable weather (cold-hot, water freeze-melt). use only with liquid_finite=1 -#weather = false # Enable nice leaves; disable for speed #new_style_leaves = true # Enable smooth lighting with simple ambient occlusion; diff --git a/src/biome.cpp b/src/biome.cpp index dca900cb..e1dfc47a 100644 --- a/src/biome.cpp +++ b/src/biome.cpp @@ -203,54 +203,3 @@ u8 BiomeDefManager::getBiomeIdByName(const char *name) { return 0; } - - -///////////////////////////// Weather - - -s16 BiomeDefManager::calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime) { - //variant 1: full random - //f32 heat = NoisePerlin3D(np_heat, p.X, env->getGameTime()/100, p.Z, seed); - - //variant 2: season change based on default heat map - const f32 offset = 20; // = np_heat->offset - const f32 scale = 20; // = np_heat->scale - const f32 range = 20; - f32 heat = NoisePerlin2D(np_heat, p.X, p.Z, seed); // 0..50..100 - - heat -= np_heat->offset; // -50..0..+50 - - // normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50, - if (np_heat->scale) - heat /= np_heat->scale / scale; // -20..0..+20 - - f32 seasonv = totaltime; - seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed - seasonv += (f32)p.X / 3000; // you can walk to area with other season - seasonv = sin(seasonv * M_PI); - heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30 - - heat += offset; // -40..0..50 - heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000 - - // daily change, hotter at sun +4, colder at night -4 - heat += 8 * (sin(cycle_shift(timeofday, -0.25) * M_PI) - 0.5); //-44..20..54 - - return heat; -} - - -s16 BiomeDefManager::calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime) { - - f32 humidity = NoisePerlin2D(np_humidity, p.X, p.Z, seed); - - f32 seasonv = totaltime; - seasonv /= 86400 * 2; // bad weather change speed (2 days) - seasonv += (f32)p.Z / 300; - humidity += 30 * sin(seasonv * M_PI); - - humidity += -12 * (sin(cycle_shift(timeofday, -0.1) * M_PI) - 0.5); - humidity = rangelim(humidity, 0, 100); - - return humidity; -} diff --git a/src/constants.h b/src/constants.h index 17f5d389..8c478ac6 100644 --- a/src/constants.h +++ b/src/constants.h @@ -89,11 +89,5 @@ with this program; if not, write to the Free Software Foundation, Inc., // Maximum hit points of a player #define PLAYER_MAX_HP 20 -/* - Environmental condition constants -*/ -#define HEAT_UNDEFINED (-0x7fff-1) -#define HUMIDITY_UNDEFINED (-0x7fff-1) - #endif diff --git a/src/content_abm.cpp b/src/content_abm.cpp index 9289035b..1ee41b2e 100644 --- a/src/content_abm.cpp +++ b/src/content_abm.cpp @@ -32,216 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" -class LiquidFlowABM : public ActiveBlockModifier { - private: - std::set contents; - - public: - LiquidFlowABM(ServerEnvironment *env, INodeDefManager *nodemgr) { - std::set liquids; - nodemgr->getIds("group:liquid", liquids); - for(std::set::const_iterator k = liquids.begin(); k != liquids.end(); k++) - contents.insert(nodemgr->get(*k).liquid_alternative_flowing); - } - virtual std::set getTriggerContents() { - return contents; - } - virtual float getTriggerInterval() - { return 10.0; } - virtual u32 getTriggerChance() - { return 10; } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) { - ServerMap *map = &env->getServerMap(); - if (map->transforming_liquid_size() > 500) - return; - map->transforming_liquid_add(p); - } -}; - -class LiquidDropABM : public ActiveBlockModifier { - private: - std::set contents; - - public: - LiquidDropABM(ServerEnvironment *env, INodeDefManager *nodemgr) { - std::set liquids; - nodemgr->getIds("group:liquid", liquids); - for(std::set::const_iterator k = liquids.begin(); k != liquids.end(); k++) - contents.insert(nodemgr->get(*k).liquid_alternative_source); - } - virtual std::set getTriggerContents() - { return contents; } - virtual std::set getRequiredNeighbors() { - std::set neighbors; - neighbors.insert("air"); - return neighbors; - } - virtual float getTriggerInterval() - { return 20.0; } - virtual u32 getTriggerChance() - { return 10; } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) { - ServerMap *map = &env->getServerMap(); - if (map->transforming_liquid_size() > 500) - return; - if ( map->getNodeNoEx(p - v3s16(0, 1, 0 )).getContent() != CONTENT_AIR // below - && map->getNodeNoEx(p - v3s16(1, 0, 0 )).getContent() != CONTENT_AIR // right - && map->getNodeNoEx(p - v3s16(-1, 0, 0 )).getContent() != CONTENT_AIR // left - && map->getNodeNoEx(p - v3s16(0, 0, 1 )).getContent() != CONTENT_AIR // back - && map->getNodeNoEx(p - v3s16(0, 0, -1)).getContent() != CONTENT_AIR // front - ) - return; - map->transforming_liquid_add(p); - } -}; - -class LiquidFreeze : public ActiveBlockModifier { - public: - LiquidFreeze(ServerEnvironment *env, INodeDefManager *nodemgr) { } - virtual std::set getTriggerContents() { - std::set s; - s.insert("group:freezes"); - return s; - } - virtual std::set getRequiredNeighbors() { - std::set s; - s.insert("air"); - s.insert("group:melts"); - return s; - } - virtual float getTriggerInterval() - { return 10.0; } - virtual u32 getTriggerChance() - { return 20; } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) { - ServerMap *map = &env->getServerMap(); - INodeDefManager *ndef = env->getGameDef()->ndef(); - - float heat = map->updateBlockHeat(env, p); - //heater = rare - content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top - //more chance to freeze if air at top - if (heat <= -1 && (heat <= -50 || (myrand_range(-50, heat) <= (c == CONTENT_AIR ? -10 : -40)))) { - content_t c_self = n.getContent(); - // making freeze not annoying, do not freeze random blocks in center of ocean - // todo: any block not water (dont freeze _source near _flowing) - bool allow = heat < -40; - // todo: make for(...) - if (!allow) { - c = map->getNodeNoEx(p - v3s16(0, 1, 0 )).getContent(); // below - if (c == CONTENT_AIR || c == CONTENT_IGNORE) - return; // do not freeze when falling - if (c != c_self && c != CONTENT_IGNORE) allow = 1; - if (!allow) { - c = map->getNodeNoEx(p - v3s16(1, 0, 0 )).getContent(); // right - if (c != c_self && c != CONTENT_IGNORE) allow = 1; - if (!allow) { - c = map->getNodeNoEx(p - v3s16(-1, 0, 0 )).getContent(); // left - if (c != c_self && c != CONTENT_IGNORE) allow = 1; - if (!allow) { - c = map->getNodeNoEx(p - v3s16(0, 0, 1 )).getContent(); // back - if (c != c_self && c != CONTENT_IGNORE) allow = 1; - if (!allow) { - c = map->getNodeNoEx(p - v3s16(0, 0, -1)).getContent(); // front - if (c != c_self && c != CONTENT_IGNORE) allow = 1; - } - } - } - } - } - if (allow) { - n.freezeMelt(ndef); - map->addNodeWithEvent(p, n); - } - } - } -}; - -class LiquidMeltWeather : public ActiveBlockModifier { - public: - LiquidMeltWeather(ServerEnvironment *env, INodeDefManager *nodemgr) { } - virtual std::set getTriggerContents() { - std::set s; - s.insert("group:melts"); - return s; - } - virtual std::set getRequiredNeighbors() { - std::set s; - s.insert("air"); - s.insert("group:freezes"); - return s; - } - virtual float getTriggerInterval() - { return 10.0; } - virtual u32 getTriggerChance() - { return 20; } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) { - ServerMap *map = &env->getServerMap(); - INodeDefManager *ndef = env->getGameDef()->ndef(); - - float heat = map->updateBlockHeat(env, p); - content_t c = map->getNodeNoEx(p - v3s16(0, -1, 0 )).getContent(); // top - if (heat >= 1 && (heat >= 40 || ((myrand_range(heat, 40)) >= (c == CONTENT_AIR ? 10 : 20)))) { - n.freezeMelt(ndef); - map->addNodeWithEvent(p, n); - env->getScriptIface()->node_falling_update(p); - } - } -}; - -class LiquidMeltHot : public ActiveBlockModifier { - public: - LiquidMeltHot(ServerEnvironment *env, INodeDefManager *nodemgr) { } - virtual std::set getTriggerContents() { - std::set s; - s.insert("group:melts"); - return s; - } - virtual std::set getRequiredNeighbors() { - std::set s; - s.insert("group:igniter"); - s.insert("group:hot"); - return s; - } - virtual float getTriggerInterval() - { return 2.0; } - virtual u32 getTriggerChance() - { return 4; } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n) { - ServerMap *map = &env->getServerMap(); - INodeDefManager *ndef = env->getGameDef()->ndef(); - n.freezeMelt(ndef); - map->addNodeWithEvent(p, n); - env->getScriptIface()->node_falling_update(p); - } -}; - -/* too buggy, later via liquid flow code -class LiquidMeltAround : public LiquidMeltHot { - public: - LiquidMeltAround(ServerEnvironment *env, INodeDefManager *nodemgr) - : LiquidMeltHot(env, nodemgr) { } - virtual std::set getRequiredNeighbors() { - std::set s; - s.insert("group:melt_around"); - return s; - } - virtual float getTriggerInterval() - { return 40.0; } - virtual u32 getTriggerChance() - { return 60; } -}; -*/ - void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) { - if (g_settings->getBool("liquid_finite")) { - env->addActiveBlockModifier(new LiquidFlowABM(env, nodedef)); - env->addActiveBlockModifier(new LiquidDropABM(env, nodedef)); - env->addActiveBlockModifier(new LiquidMeltHot(env, nodedef)); - //env->addActiveBlockModifier(new LiquidMeltAround(env, nodedef)); - if (env->m_use_weather) { - env->addActiveBlockModifier(new LiquidFreeze(env, nodedef)); - env->addActiveBlockModifier(new LiquidMeltWeather(env, nodedef)); - } - } + } diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index c39fa54a..ff3bf5b8 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -244,13 +244,8 @@ void set_default_settings(Settings *settings) settings->setDefault("movement_gravity", "9.81"); //liquid stuff - settings->setDefault("liquid_finite", "false"); settings->setDefault("liquid_loop_max", "10000"); settings->setDefault("liquid_update", "1.0"); - settings->setDefault("liquid_relax", "2"); - settings->setDefault("liquid_fast_flood", "1"); - settings->setDefault("underground_springs", "1"); - settings->setDefault("weather", "false"); //mapgen stuff settings->setDefault("mg_name", "v6"); diff --git a/src/environment.cpp b/src/environment.cpp index bc1b59d8..fa7ce2ae 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -321,7 +321,6 @@ ServerEnvironment::ServerEnvironment(ServerMap *map, m_recommended_send_interval(0.1), m_max_lag_estimate(0.1) { - m_use_weather = g_settings->getBool("weather"); } ServerEnvironment::~ServerEnvironment() diff --git a/src/environment.h b/src/environment.h index 48d099bf..5062b9c3 100644 --- a/src/environment.h +++ b/src/environment.h @@ -314,9 +314,6 @@ public: void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } float getMaxLagEstimate() { return m_max_lag_estimate; } - // is weather active in this environment? - bool m_use_weather; - std::set* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }; private: diff --git a/src/game.cpp b/src/game.cpp index 1ad06acb..a4a21e0a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1642,8 +1642,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, Hud hud(driver, smgr, guienv, font, text_height, gamedef, player, &local_inventory); - bool use_weather = g_settings->getBool("weather"); - core::stringw str = L"Minetest ["; str += driver->getName(); str += "]"; @@ -3111,8 +3109,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, fog_range = 100000*BS; else { fog_range = draw_control.wanted_range*BS + 0.0*MAP_BLOCKSIZE*BS; - if(use_weather) - fog_range *= (1.5 - 1.4*(float)client.getEnv().getClientMap().getHumidity(pos_i)/100); fog_range = MYMIN(fog_range, (draw_control.farthest_drawn+20)*BS); fog_range *= 0.9; } @@ -3262,9 +3258,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input, <<", "<<(player_position.Y/BS) <<", "<<(player_position.Z/BS) <<") (yaw="<<(wrapDegrees_0_360(camera_yaw)) - <<") (t="<setText(narrow_to_wide(os.str()).c_str()); guitext2->setVisible(true); diff --git a/src/map.cpp b/src/map.cpp index 8f612aea..de8e1107 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1100,7 +1100,6 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, /* Add neighboring liquid nodes and the node itself if it is liquid (=water node was added) to transform queue. - note: todo: for liquid_finite enough to add only self node */ v3s16 dirs[7] = { v3s16(0,0,0), // self @@ -1292,7 +1291,6 @@ void Map::removeNodeAndUpdate(v3s16 p, /* Add neighboring liquid nodes and this node to transform queue. (it's vital for the node itself to get updated last.) - note: todo: for liquid_finite enough to add only self node */ v3s16 dirs[7] = { v3s16(0,0,1), // back @@ -1619,7 +1617,6 @@ struct NodeNeighbor { NeighborType t; v3s16 p; bool l; //can liquid - bool i; //infinity }; void Map::transforming_liquid_add(v3s16 p) { @@ -1630,383 +1627,8 @@ s32 Map::transforming_liquid_size() { return m_transforming_liquid.size(); } -const v3s16 g_7dirs[7] = -{ - // +right, +top, +back - v3s16( 0,-1, 0), // bottom - v3s16( 0, 0, 0), // self - v3s16( 0, 0, 1), // back - v3s16( 0, 0,-1), // front - v3s16( 1, 0, 0), // right - v3s16(-1, 0, 0), // left - v3s16( 0, 1, 0) // top -}; - -#define D_BOTTOM 0 -#define D_TOP 6 -#define D_SELF 1 - -void Map::transformLiquidsFinite(std::map & modified_blocks) -{ - INodeDefManager *nodemgr = m_gamedef->ndef(); - - DSTACK(__FUNCTION_NAME); - //TimeTaker timer("transformLiquids()"); - - u32 loopcount = 0; - u32 initial_size = m_transforming_liquid.size(); - - u8 relax = g_settings->getS16("liquid_relax"); - bool fast_flood = g_settings->getS16("liquid_fast_flood"); - int water_level = g_settings->getS16("water_level"); - - // list of nodes that due to viscosity have not reached their max level height - UniqueQueue must_reflow, must_reflow_second; - - // List of MapBlocks that will require a lighting update (due to lava) - std::map lighting_modified_blocks; - - u16 loop_max = g_settings->getU16("liquid_loop_max"); - - //if (m_transforming_liquid.size() > 0) errorstream << "Liquid queue size="< 0) - { - // This should be done here so that it is done when continue is used - if (loopcount >= initial_size || loopcount >= loop_max) - break; - loopcount++; - /* - Get a queued transforming liquid node - */ - v3s16 p0 = m_transforming_liquid.pop_front(); - u16 total_level = 0; - // surrounding flowing liquid nodes - NodeNeighbor neighbors[7]; - // current level of every block - s8 liquid_levels[7] = {-1, -1, -1, -1, -1, -1, -1}; - // target levels - s8 liquid_levels_want[7] = {-1, -1, -1, -1, -1, -1, -1}; - s8 can_liquid_same_level = 0; - content_t liquid_kind = CONTENT_IGNORE; - content_t liquid_kind_flowing = CONTENT_IGNORE; - /* - Collect information about the environment - */ - const v3s16 *dirs = g_7dirs; - for (u16 i = 0; i < 7; i++) { - NeighborType nt = NEIGHBOR_SAME_LEVEL; - switch (i) { - case D_TOP: - nt = NEIGHBOR_UPPER; - break; - case D_BOTTOM: - nt = NEIGHBOR_LOWER; - break; - } - v3s16 npos = p0 + dirs[i]; - - neighbors[i].n = getNodeNoEx(npos); - neighbors[i].t = nt; - neighbors[i].p = npos; - neighbors[i].l = 0; - neighbors[i].i = 0; - NodeNeighbor & nb = neighbors[i]; - - switch (nodemgr->get(nb.n.getContent()).liquid_type) { - case LIQUID_NONE: - if (nb.n.getContent() == CONTENT_AIR) { - liquid_levels[i] = 0; - nb.l = 1; - } - break; - case LIQUID_SOURCE: - // if this node is not (yet) of a liquid type, - // choose the first liquid type we encounter - if (liquid_kind_flowing == CONTENT_IGNORE) - liquid_kind_flowing = nodemgr->getId( - nodemgr->get(nb.n).liquid_alternative_flowing); - if (liquid_kind == CONTENT_IGNORE) - liquid_kind = nb.n.getContent(); - if (nb.n.getContent() == liquid_kind) { - liquid_levels[i] = nb.n.getLevel(nodemgr); //LIQUID_LEVEL_SOURCE; - nb.l = 1; - nb.i = (nb.n.param2 & LIQUID_INFINITY_MASK); - } - break; - case LIQUID_FLOWING: - // if this node is not (yet) of a liquid type, - // choose the first liquid type we encounter - if (liquid_kind_flowing == CONTENT_IGNORE) - liquid_kind_flowing = nb.n.getContent(); - if (liquid_kind == CONTENT_IGNORE) - liquid_kind = nodemgr->getId( - nodemgr->get(nb.n).liquid_alternative_source); - if (nb.n.getContent() == liquid_kind_flowing) { - liquid_levels[i] = nb.n.getLevel(nodemgr); //(nb.n.param2 & LIQUID_LEVEL_MASK); - nb.l = 1; - } - break; - } - - if (nb.l && nb.t == NEIGHBOR_SAME_LEVEL) - ++can_liquid_same_level; - if (liquid_levels[i] > 0) - total_level += liquid_levels[i]; - - /* - infostream << "get node i=" <<(int)i<<" " << PP(npos) << " c=" - << nb.n.getContent() <<" p0="<< (int)nb.n.param0 <<" p1=" - << (int)nb.n.param1 <<" p2="<< (int)nb.n.param2 << " lt=" - << nodemgr->get(nb.n.getContent()).liquid_type - //<< " lk=" << liquid_kind << " lkf=" << liquid_kind_flowing - << " l="<< nb.l << " inf="<< nb.i << " nlevel=" << (int)liquid_levels[i] - << " tlevel=" << (int)total_level << " cansame=" - << (int)can_liquid_same_level << std::endl; - */ - } - - if (liquid_kind == CONTENT_IGNORE || - !neighbors[D_SELF].l || - total_level <= 0) - continue; - - // fill bottom block - if (neighbors[D_BOTTOM].l) { - liquid_levels_want[D_BOTTOM] = total_level > LIQUID_LEVEL_SOURCE ? - LIQUID_LEVEL_SOURCE : total_level; - total_level -= liquid_levels_want[D_BOTTOM]; - } - - //relax up - if (relax && ((p0.Y == water_level) || (fast_flood && p0.Y <= water_level)) && liquid_levels[D_TOP] == 0 && - liquid_levels[D_BOTTOM] == LIQUID_LEVEL_SOURCE && - total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level- - (can_liquid_same_level - relax) && - can_liquid_same_level >= relax + 1) { - total_level = LIQUID_LEVEL_SOURCE * can_liquid_same_level; - } - - // prevent lakes in air above unloaded blocks - if (liquid_levels[D_TOP] == 0 && (p0.Y > water_level) && neighbors[D_BOTTOM].n.getContent() == CONTENT_IGNORE && !(loopcount % 3)) { - --total_level; - } - - // calculate self level 5 blocks - u8 want_level = - total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level - ? LIQUID_LEVEL_SOURCE - : total_level / can_liquid_same_level; - total_level -= want_level * can_liquid_same_level; - - //relax down - if (relax && p0.Y == water_level + 1 && liquid_levels[D_TOP] == 0 && - liquid_levels[D_BOTTOM] == LIQUID_LEVEL_SOURCE && want_level == 0 && - total_level <= (can_liquid_same_level - relax) && - can_liquid_same_level >= relax + 1) { - total_level = 0; - } - - for (u16 ii = D_SELF; ii < D_TOP; ++ii) { // fill only same level - if (!neighbors[ii].l) - continue; - liquid_levels_want[ii] = want_level; - if (liquid_levels_want[ii] < LIQUID_LEVEL_SOURCE && total_level > 0) { - if (loopcount % 3 || liquid_levels[ii] <= 0){ - if (liquid_levels[ii] > liquid_levels_want[ii]) { - ++liquid_levels_want[ii]; - --total_level; - } - } else if (neighbors[ii].l > 0){ - ++liquid_levels_want[ii]; - --total_level; - } - } - } - - for (u16 ii = 0; ii < 7; ++ii) { - if (total_level < 1) break; - if (liquid_levels_want[ii] >= 0 && - liquid_levels_want[ii] < LIQUID_LEVEL_SOURCE) { - ++liquid_levels_want[ii]; - --total_level; - } - } - - // fill top block if can - if (neighbors[D_TOP].l) { - liquid_levels_want[D_TOP] = total_level > LIQUID_LEVEL_SOURCE ? - LIQUID_LEVEL_SOURCE : total_level; - total_level -= liquid_levels_want[D_TOP]; - } - - for (u16 ii = 0; ii < 7; ii++) // infinity and cave flood optimization - if ( neighbors[ii].i || - (liquid_levels_want[ii] >= 0 && - (fast_flood && p0.Y < water_level && - (initial_size >= 1000 - && ii != D_TOP - && want_level >= LIQUID_LEVEL_SOURCE/4 - && can_liquid_same_level >= 5 - && liquid_levels[D_TOP] >= LIQUID_LEVEL_SOURCE)))) - liquid_levels_want[ii] = LIQUID_LEVEL_SOURCE; - - /* - if (total_level > 0) //|| flowed != volume) - infostream <<" AFTER level=" << (int)total_level - //<< " flowed="<ndef(); DSTACK(__FUNCTION_NAME); @@ -2385,26 +2007,6 @@ void Map::removeNodeTimer(v3s16 p) block->m_node_timers.remove(p_rel); } -s16 Map::getHeat(v3s16 p) -{ - MapBlock *block = getBlockNoCreateNoEx(getNodeBlockPos(p)); - if(block != NULL) { - return block->heat; - } - //errorstream << "No heat for " << p.X<<"," << p.Z << std::endl; - return 0; -} - -s16 Map::getHumidity(v3s16 p) -{ - MapBlock *block = getBlockNoCreateNoEx(getNodeBlockPos(p)); - if(block != NULL) { - return block->humidity; - } - //errorstream << "No humidity for " << p.X<<"," << p.Z << std::endl; - return 0; -} - /* ServerMap */ @@ -2818,29 +2420,6 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, <<","<getEnv(); - for(s16 x=blockpos_min.X-extra_borders.X; - x<=blockpos_max.X+extra_borders.X; x++) - for(s16 z=blockpos_min.Z-extra_borders.Z; - z<=blockpos_max.Z+extra_borders.Z; z++) - for(s16 y=blockpos_min.Y-extra_borders.Y; - y<=blockpos_max.Y+extra_borders.Y; y++) - { - v3s16 p(x, y, z); - MapBlock *block = getBlockNoCreateNoEx(p); - block->heat_last_update = 0; - block->humidity_last_update = 0; - if (senv->m_use_weather) { - updateBlockHeat(senv, p * MAP_BLOCKSIZE, block); - updateBlockHumidity(senv, p * MAP_BLOCKSIZE, block); - } else { - block->heat = HEAT_UNDEFINED; - block->humidity = HUMIDITY_UNDEFINED; - } - } #if 0 if(enable_mapgen_debug_info) @@ -3176,18 +2755,6 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d) void ServerMap::prepareBlock(MapBlock *block) { ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv(); - - // Calculate weather conditions - block->heat_last_update = 0; - block->humidity_last_update = 0; - if (senv->m_use_weather) { - v3s16 p = block->getPos() * MAP_BLOCKSIZE; - updateBlockHeat(senv, p, block); - updateBlockHumidity(senv, p, block); - } else { - block->heat = HEAT_UNDEFINED; - block->humidity = HUMIDITY_UNDEFINED; - } } s16 ServerMap::findGroundLevel(v2s16 p2d) @@ -3917,48 +3484,6 @@ void ServerMap::PrintInfo(std::ostream &out) out<<"ServerMap: "; } -s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block) -{ - u32 gametime = env->getGameTime(); - - if (block) { - if (gametime - block->heat_last_update < 10) - return block->heat; - } else { - block = getBlockNoCreateNoEx(getNodeBlockPos(p)); - } - - f32 heat = m_emerge->biomedef->calcBlockHeat(p, getSeed(), - env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed()); - - if(block) { - block->heat = heat; - block->heat_last_update = gametime; - } - return heat; -} - -s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block) -{ - u32 gametime = env->getGameTime(); - - if (block) { - if (gametime - block->humidity_last_update < 10) - return block->humidity; - } else { - block = getBlockNoCreateNoEx(getNodeBlockPos(p)); - } - - f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, getSeed(), - env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed()); - - if(block) { - block->humidity = humidity; - block->humidity_last_update = gametime; - } - return humidity; -} - /* MapVoxelManipulator */ diff --git a/src/map.h b/src/map.h index 191cf5f9..c2725d3d 100644 --- a/src/map.h +++ b/src/map.h @@ -304,7 +304,6 @@ public: virtual void PrintInfo(std::ostream &out); void transformLiquids(std::map & modified_blocks); - void transformLiquidsFinite(std::map & modified_blocks); /* Node metadata @@ -351,9 +350,6 @@ public: void transforming_liquid_add(v3s16 p); s32 transforming_liquid_size(); - virtual s16 getHeat(v3s16 p); - virtual s16 getHumidity(v3s16 p); - protected: friend class LuaVoxelManip; @@ -504,9 +500,6 @@ public: u64 getSeed(); s16 getWaterLevel(); - virtual s16 updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL); - virtual s16 updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block = NULL); - private: // Emerge manager EmergeManager *m_emerge; diff --git a/src/mapblock.cpp b/src/mapblock.cpp index eafb956d..95e54fb3 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -43,10 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy): - heat(0), - humidity(0), - heat_last_update(0), - humidity_last_update(0), m_parent(parent), m_pos(pos), m_gamedef(gamedef), @@ -647,8 +643,8 @@ void MapBlock::serializeNetworkSpecific(std::ostream &os, u16 net_proto_version) if(net_proto_version >= 21){ int version = 1; writeU8(os, version); - writeF1000(os, heat); - writeF1000(os, humidity); + writeF1000(os, 0); // deprecated heat + writeF1000(os, 0); // deprecated humidity } } @@ -764,8 +760,8 @@ void MapBlock::deSerializeNetworkSpecific(std::istream &is) //if(version != 1) // throw SerializationError("unsupported MapBlock version"); if(version >= 1) { - heat = readF1000(is); - humidity = readF1000(is); + readF1000(is); // deprecated heat + readF1000(is); // deprecated humidity } } catch(SerializationError &e) diff --git a/src/mapblock.h b/src/mapblock.h index 501ab75d..3879c5b0 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -513,11 +513,6 @@ public: NodeMetadataList m_node_metadata; NodeTimerList m_node_timers; StaticObjectList m_static_objects; - - s16 heat; - s16 humidity; - u32 heat_last_update; - u32 humidity_last_update; private: /* diff --git a/src/mapgen.cpp b/src/mapgen.cpp index a7e9d2e0..5e393901 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -979,8 +979,6 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) { void Mapgen::updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax) { bool isliquid, wasliquid, rare; v3s16 em = vm->m_area.getExtent(); - rare = g_settings->getBool("liquid_finite"); - int rarecnt = 0; for (s16 z = nmin.Z; z <= nmax.Z; z++) { for (s16 x = nmin.X; x <= nmax.X; x++) { @@ -990,8 +988,8 @@ void Mapgen::updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nm for (s16 y = nmax.Y; y >= nmin.Y; y--) { isliquid = ndef->get(vm->m_data[i]).isLiquid(); - // there was a change between liquid and nonliquid, add to queue. no need to add every with liquid_finite - if (isliquid != wasliquid && (!rare || !(rarecnt++ % 36))) + // there was a change between liquid and nonliquid, add to queue. + if (isliquid != wasliquid) trans_liquid->push_back(v3s16(x, y, z)); wasliquid = isliquid; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 6447866c..37fa167e 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -765,7 +765,6 @@ int ModApiEnvMod::l_spawn_tree(lua_State *L) return 1; } - // minetest.transforming_liquid_add(pos) int ModApiEnvMod::l_transforming_liquid_add(lua_State *L) { @@ -776,28 +775,6 @@ int ModApiEnvMod::l_transforming_liquid_add(lua_State *L) return 1; } -// minetest.get_heat(pos) -// pos = {x=num, y=num, z=num} -int ModApiEnvMod::l_get_heat(lua_State *L) -{ - GET_ENV_PTR; - - v3s16 pos = read_v3s16(L, 1); - lua_pushnumber(L, env->getServerMap().updateBlockHeat(env, pos)); - return 1; -} - -// minetest.get_humidity(pos) -// pos = {x=num, y=num, z=num} -int ModApiEnvMod::l_get_humidity(lua_State *L) -{ - GET_ENV_PTR; - - v3s16 pos = read_v3s16(L, 1); - lua_pushnumber(L, env->getServerMap().updateBlockHumidity(env, pos)); - return 1; -} - // minetest.forceload_block(blockpos) // blockpos = {x=num, y=num, z=num} int ModApiEnvMod::l_forceload_block(lua_State *L) @@ -855,8 +832,6 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(find_path); API_FCT(line_of_sight); API_FCT(transforming_liquid_add); - API_FCT(get_heat); - API_FCT(get_humidity); API_FCT(forceload_block); API_FCT(forceload_free_block); } diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 7e1cabe3..8bf599b0 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -148,9 +148,6 @@ private: // minetest.transforming_liquid_add(pos) static int l_transforming_liquid_add(lua_State *L); - static int l_get_heat(lua_State *L); - static int l_get_humidity(lua_State *L); - // minetest.forceload_block(blockpos) // forceloads a block static int l_forceload_block(lua_State *L); diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 64511b5b..10ec5771 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -218,7 +218,6 @@ void sendAnnounce(std::string action, const std::vector & clients_n server["dedicated"] = g_settings->get("server_dedicated"); server["privs"] = g_settings->get("default_privs"); server["rollback"] = g_settings->getBool("enable_rollback_recording"); - server["liquid_finite"] = g_settings->getBool("liquid_finite"); server["mapgen"] = g_settings->get("mg_name"); server["can_see_far_names"] = g_settings->getBool("unlimited_player_transfer_distance"); server["mods"] = Json::Value(Json::arrayValue); From 4977b736e3be522a6becaabbd53d380a767a3a53 Mon Sep 17 00:00:00 2001 From: proller Date: Sat, 19 Apr 2014 02:24:45 +0400 Subject: [PATCH 53/53] Fix warnings --- src/game.cpp | 1 - src/map.cpp | 1 - src/mapgen.cpp | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index a4a21e0a..9f1609aa 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2677,7 +2677,6 @@ void the_game(bool &kill, bool random_input, InputHandler *input, camera.step(dtime); v3f player_position = player->getPosition(); - v3s16 pos_i = floatToInt(player_position, BS); v3f camera_position = camera.getPosition(); v3f camera_direction = camera.getDirection(); f32 camera_fov = camera.getFovMax(); diff --git a/src/map.cpp b/src/map.cpp index de8e1107..86ad9ecb 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2754,7 +2754,6 @@ MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d) } void ServerMap::prepareBlock(MapBlock *block) { - ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv(); } s16 ServerMap::findGroundLevel(v2s16 p2d) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 5e393901..1a31a8bc 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -977,7 +977,7 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) { void Mapgen::updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax) { - bool isliquid, wasliquid, rare; + bool isliquid, wasliquid; v3s16 em = vm->m_area.getExtent(); for (s16 z = nmin.Z; z <= nmax.Z; z++) {